Emerald

Open source interaction monitor and logger

Emerald listens for event interactions and logs them to a database.

Emerald is a privacy focused interaction monitor and logger. Emerald does not collect or store personal identifiable information or network address information.

Distribution

Emerald is distributed as open source and without license restriction. Information about the license is referenced in the included document: license.txt. Information about development is referenced in the included documents: notice.txt, version.txt.

Emerald 0.2.1 is written in the Go 1.11.0 programming language and is distributed as open source code.

Compilation

Emerald is written in the Go programming language and depends on the standard library and the PostgreSQL database driver to compile. Emerald is developed and supported on select systems: linux/amd64, linux/arm64, darwin/amd64, darwin/arm64.

Emerald compiles with different options: test, run, build, clean, install. The compile script is optional and automates the compile process.

% ./compile.sh run

Operation

Emerald is operated through a command line interface. The default path is /usr/local/bin/emerald. The default paths can be changed with command options.

For security purposes, the process should be restricted to a dedicated emerald user and emerald group on the system.

Help

Print the help document.

% emerald -help

Version

Print the version number.

% emerald -version

Verbose

Set the verbose log mode. For security purposes, verbose should be restricted to console log sessions.

% emerald -verbose

Input Log

Set the standard input log file path. The default path is /usr/local/var/log/emerald/input.log.

% emerald -log-input path

Output Log

Set the standard output log file path. The default path is /usr/local/var/log/emerald/output.log.

% emerald -log-output path

Error Log

Set the standard error log file path. The default path is /usr/local/var/log/emerald/error.log.

% emerald -log-error path

Configuration

Set the configuration file path. The default path is /usr/local/etc/emerald.cfg.

% emerald -cfg path

Configuration

Emerald is intended to operate behind a reverse proxy. For security purposes, the configuration file should be restricted to a dedicated emerald user and emerald group on the system.

Global Configuration

The global configuration section defines: server.

Define multiple servers for concurrent server processes.

{
  "server": [
    { ... },
    { ... }
  ]
}

Server Configuration

The server configuration section defines: hostname, port, database hostname, database port, database name, database username, database password.

{
  "hostname": "localhost",
  "port": "0000",
  "database": {
    "hostname": "localhost",
    "port": "0000",
    "name": "example",
    "authentication": {
      "username": "example",
      "password": "example"
    }
  }
}

Interface

Emerald is controlled through a programming interface. The interface examples are provided in the Javascript programming language.

Request Log

The request log function will pass log data to the database.

function requestLog(data) {
  fetch("https://localhost/emerald", {
    method: "POST",
    headers: {
      "Accept": "application/json; charset=utf-8",
      "Content-Type": "application/json; charset=utf-8"
    },
    body: JSON.stringify(data)
  })
}

Generate Log

The generate log function will register different request modes and pass the generated log to the request log function.

function generateLog(event, mode) {
  switch (mode) {
    case "example":
      requestLog({
        request: {
          event:    `${event.target}`,
          location: `${window.location.href}`,
          referrer: `${document.referrer}`
        },
        device: {
          language: `${window.navigator.language}`,
          version:  `${window.navigator.userAgent}`
        },
        session: `${window.sessionStorage.getItem("uid")}`
      });
      break;
    default:
      return null;
      break;
  }
}

Generate Identifier

The generate identifier function will generate a unique session identifier. The identifier is used to group session requests and nothing else.

function generateIdentifier() {
  const value = new Uint32Array(32);
  const source = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  let identifier = "";
  
  window.crypto.getRandomValues(value);
  
  for (let index = 0; index < 32; index++) {
    identifier += source[value[index] % source.length];
  }
  
  return identifier;
}

Store Identifier

The store identifier function will store the identifier in the standard storage interface. The identifier is deleted when the session is closed.

function storeIdentifier() {
  if (window.sessionStorage.getItem("uid") == null) {
    window.sessionStorage.setItem("uid", generateIdentifier());
  }
}