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.


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 the latest version and is distributed as open source code.


Emerald is written in the Go programming language and depends on the standard library and PostgreSQL database driver to compile. Go is compatible with common server operating systems and processor architectures. 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


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.


Print the help document.

% emerald -help


Print the version number.

% emerald -version


Set the verbose log mode. For security purposes, the verbose log is not recommended.

% 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


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

% emerald -cfg path


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"


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":
        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")}`
      return null;

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 = "";
  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());