A simple Web Service for for capture and persisting HTTP events, offering a find interface
  • Java 64.8%
  • Python 35.2%
Find a file
2025-06-24 14:34:08 +02:00
zink-java Added a Java implementation of the Zink server 2025-06-24 14:34:08 +02:00
zink-python intermidiate work 2025-06-24 07:24:56 +02:00
.gitignore Initial commit 2025-01-29 15:28:52 +01:00
cert.pem initial commit 2025-02-01 19:56:29 +01:00
key.pem initial commit 2025-02-01 19:56:29 +01:00
LICENSE Initial commit 2025-01-29 15:28:52 +01:00
README.md Added a Java implementation of the Zink server 2025-06-24 14:34:08 +02:00
zink-api-keys.json add java implementation 2025-06-18 17:28:27 +02:00
zink-server-mongo.json intermidiate work 2025-06-23 16:13:11 +02:00
zink-server-sqlite3.json add java implementation 2025-06-18 17:28:27 +02:00

Zink - An Event Sink

About Zink

If you need to log events to a remote host, Zink might be a tool worth exploring.

Zink is a simple Python HTTP server application that listens for HTTP requests to either save or find events. The idea is that client applications or scripts can send Save or Find requests to the server. (There is now also a Java implementation of the Zink server)

The server uses an embedded SQLite3 or MongoDB database to persist events.

Data

The Zink server can both Save and Find events. The data attributes associated with an event are:

  • application: String
  • tag: String (optional)
  • time: String (format: 'yyyy-MM-dd HH:mm:ss.SSS')
  • data: String

When the server persists an event, it automatically sets the time for the event.

Zink Clients

To interact with a Zink server, a client application will use HTTP/HTTPS connections. Requests are sent as HTTP/HTTPS POST requests for Save and Find.

Data can also be retrieved (i.e., FIND) from the Zink server via a standard browser using GET requests.

POST requests are JSON messages with the following structure:

SAVE events The URL path to the POST save entry is "/save" e.g. https:///save The post data in a save have the following Json format

{
  'application' : string
  'tag' : string
  'data' : string
}

NOTE:
'data.tag' is optional in save requests

FIND events The URL path to the POST find entry is "/save" e.g. https:///find The post data in a find have the following Json format

{
  'application': string
  'tag': string,
  'after': string,
  'before': string,
  'limit': int
}

NOTE:
'application' is mandatory
'data.tag','data.after','data.before' and limit are optional
'data.after' and 'data.before' are time strings have the following format 'yyyy-MM-dd HH:mm:ss.SSS'. They do not need to be complete. The time strings will be padded by server if not being fully specified.
_'limit' specifies max number of events that should be retrieved, latest first. If omitted the server will set the limit to the MAX Integer value.

GET Requests

It's possible do find Zink events directly from an ordinary browser via accessing a Zink server URL like

https://localhost:8282/FIND?apikey=6ad345f621&application=frotz&tag=foo&before=2025-01-11&after=2025-01-01 20:22

NOTE:
'application' is a mandatory query parameter
'apikey' maybe mandatory or not depending on the server configuration
remaining parameters are optional \

Server Configuration

The Zink server does take one parameter a JSON configuration file location The configuration file has the following format

For Sqlite3 usage

{
    "verbose" : true,
    "logfile" : null,
    "authorization" : {
        "file": "../zink-api-keys.json",
        "save_restricted": true,
        "find_restricted": true
    },
   "http_port": "8888",
   "interface" : "0.0.0.0",
   "ssl": {
      "key": "../key.pem",
      "cert": "../cert.pem"
   },
  "database" : {
      "type" : "sqlite3",
      "configuration" :  {
        "db_file" : "../zink.db"}
  }
}

For Mongodb usage

{
  "verbose" : true,
  "logfile" : null,
  "authorization" : {
    "file": "../zink-api-keys.json",
    "save-restricted": true,
    "find-restricted": false
  },
  "http_port": "8888",
  "interface" : "0.0.0.0",
  "ssl": {
    "key": "../key.pem",
    "cert": "../cert.pem"
  },
  "database" : {
    "type" : "mongodb",
    "configuration" :  {
      "host" : "localhost",
      "port" :  27017,
      "db" :  "zink"}
  }
}

NOTE:
The Zink server uses a simple API key-based authorization mechanism. If 'authorization' is present in the configuration file, the server will validate incoming requests to ensure they are authorized. Validation for Save and Find requests can be enabled or disabled using the save_restricted and find_restricted attributes, respectively. If 'authorization' is not present in the configuration file, no request validation will be performed.
If 'logfile' is not present or null loging will be done to STDOUT
If you would like the server to run SSL you have to generate a SSL certificate. This can be done with the following command

$ openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem

Zink Service as System Service

You might want to run the Zink service as a system service. In that case you have to create a system service file. A simple example for linux would look like

Name the file zink.service

[Unit]
Description=Zink event server

[Service]
User=bertilsson
WorkingDirectory=/usr/local/zink
ExecStart=/usr/bin/python3 /usr/local/zink/zink-server.py -cfg=zink-server-sqlite3.json

[Install]
WantedBy=multi-user.target

On Fedora and Ubunto the file should be placed in the directory /lib/systemd/system

You have to enable the service with the following command

$ sudo systemctl enable zink.service

The service could then be started with the following command

$ sudo systemctl start zink.service

The Zink service will do some progress logging to the system log. You can see the actual status of the Zink service with the following command

$ sudo systemctl status zink.service

The system logging events can be viewed with the following commands

$ sudo journalctl -u zink
$ sudo journalctl -u zink --since="30 minutes"

The rest is in the code