• Stars
    star
    212
  • Rank 179,146 (Top 4 %)
  • Language
    Elixir
  • License
    MIT License
  • Created about 7 years ago
  • Updated 7 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

JSON console backend for Elixir Logger.

LoggerJSON

Build Status Coverage Status Module Version Hex Docs Hex Download Total License Last Updated Static Analysis Status

JSON console back-end for Elixir Logger.

It can be used as drop-in replacement for default :console Logger back-end in cases where you use Google Cloud Logger, DataDog or other JSON-based log collectors. After adding this back-end you may also be interested in redirecting otp and sasl reports to Logger (see "Error Logger configuration" section).

Minimum supported Erlang/OTP version is 20.

Log Format

LoggerJSON provides three JSON formatters out of the box and allows developers to implement a custom one.

BasicLogger

The LoggerJSON.Formatters.BasicLogger formatter provides a generic JSON formatted message with no vendor specific entries in the payload. A sample log entry from LoggerJSON.Formatters.BasicLogger looks like the following:

{
  "time": "2020-04-02T11:59:06.710Z",
  "severity": "debug",
  "message": "hello",
  "metadata": {
    "user_id": 13
  }
}

GoogleCloudLogger

Generates JSON that is compatible with the Google Cloud Logger LogEntry format:

{
  "message":"hello",
  "logging.googleapis.com/sourceLocation":{
    "file":"/os/logger_json/test/unit/logger_json_test.exs",
    "function":"Elixir.LoggerJSONGoogleTest.test metadata can be configured/1",
    "line":71
  },
  "severity":"DEBUG",
  "time":"2018-10-19T01:10:49.582Z",
  "user_id":13
}

Notice that GKE doesn't allow to set certain fields of the LogEntry, so support is limited. The results in Google Cloud Logger would looks something like this:

{
  "httpRequest":{
    "latency":"0.350s",
    "remoteIp":"::ffff:10.142.0.2",
    "requestMethod":"GET",
    "requestPath":"/",
    "requestUrl":"http://10.16.0.70/",
    "status":200,
    "userAgent":"kube-probe/1.10+"
  },
  "insertId":"1g64u74fgmqqft",
  "jsonPayload":{
    "message":"",
    "phoenix":{
      "action":"index",
      "controller":"Elixir.MyApp.Web.PageController",
    },
    "request_id":"2lfbl1r3m81c40e5v40004c2",
    "vm":{
      "hostname":"myapp-web-66979fc-vbk4q",
      "pid":1,
    }
  },
  "logName":"projects/hammer-staging/logs/stdout",
  "metadata":{
    "systemLabels":{},
    "userLabels":{}
  },
  "operation":{
    "id":"2lfbl1r3m81c40e5v40004c2"
  },
  "receiveTimestamp":"2018-10-18T14:33:35.515253723Z",
  "resource":{},
  "severity":"INFO",
  "sourceLocation":{
    "file":"iex",
    "function":"Elixir.LoggerJSON.Plug.call/2",
    "line":"36"
  },
  "timestamp":"2018-10-18T14:33:33.263Z"
}

DatadogLogger

Adheres to the default standard attribute list.

{
  "domain": ["elixir"],
  "duration": 3863403,
  "http": {
    "url": "http://localhost/create-account",
    "status_code": 200,
    "method": "GET",
    "referer": "http://localhost:4000/login",
    "request_id": "http_FlDCOItxeudZJ20AAADD",
    "useragent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36",
    "url_details": {
      "host": "localhost",
      "port": 4000,
      "path": "/create-account",
      "queryString": "",
      "scheme": "http"
    }
  },
  "logger": {
    "thread_name": "#PID<0.1042.0>",
    "method_name": "Elixir.LoggerJSON.Plug.call/2"
  },
  "message": "",
  "network": {
    "client": {
      "ip": "127.0.0.1"
    }
  },
  "phoenix": {
    "controller": "Elixir.RecognizerWeb.Accounts.UserRegistrationController",
    "action": "new"
  },
  "request_id": "http_FlDCOItxeudZJ20AAADD",
  "syslog": {
    "hostname": [10, 10, 100, 100, 100, 100, 100],
    "severity": "info",
    "timestamp": "2020-12-14T19:16:55.088Z"
  }
}

Custom formatters

You can change this structure by implementing LoggerJSON.Formatter behaviour and passing module name to :formatter config option. Example module can be found in LoggerJSON.Formatters.GoogleCloudLogger.

config :logger_json, :backend,
  formatter: MyFormatterImplementation

Installation

It's available on Hex, the package can be installed as:

  1. Add :logger_json to your list of dependencies in mix.exs:
def deps do
  [{:logger_json, "~> 5.1"}]
end
  1. Set configuration in your config/config.exs:
config :logger_json, :backend,
  metadata: :all,
  json_encoder: Jason,
  formatter: LoggerJSON.Formatters.GoogleCloudLogger

Some integrations (for eg. Plug) use metadata to log request and response parameters. You can reduce log size by replacing :all (which means log all metadata) with a list of the ones that you actually need.

Beware that LoggerJSON always ignores some metadata keys, but formatters like GoogleCloudLogger and DatadogLogger still persist those metadata values into a structured output. This behavior is similar to the default Elixir logger backend.

  1. Replace default Logger :console back-end with LoggerJSON:
config :logger,
  backends: [LoggerJSON]
  1. Optionally. Log requests and responses by replacing a Plug.Logger in your endpoint with a:
plug LoggerJSON.Plug

LoggerJSON.Plug is configured by default to use LoggerJSON.Plug.MetadataFormatters.GoogleCloudLogger. You can replace it with the :metadata_formatter config option.

  1. Optionally. Use Ecto telemetry for additional metadata:

Attach telemetry handler for Ecto events in start/2 function in application.ex

:ok =
  :telemetry.attach(
    "logger-json-ecto",
    [:my_app, :repo, :query],
    &LoggerJSON.Ecto.telemetry_logging_handler/4,
    :debug
  )

Prevent duplicate logging of events, by setting log configuration option to false

config :my_app, MyApp.Repo,
  adapter: Ecto.Adapters.Postgres,
  log: false

Dynamic configuration

For dynamically configuring the endpoint, such as loading data from environment variables or configuration files, LoggerJSON provides an :on_init option that allows developers to set a module, function and list of arguments that is invoked when the endpoint starts.

config :logger_json, :backend,
  on_init: {YourApp.Logger, :load_from_system_env, []}

Encoders support

You can replace default Jason encoder with other module that supports encode_to_iodata!/1 function and encoding fragments.

Documentation

The docs can be found at https://hexdocs.pm/logger_json

Thanks

Many source code has been taken from original Elixir Logger :console back-end source code, so I want to thank all it's authors and contributors.

Part of LoggerJSON.Plug module have origins from plug_logger_json by @bleacherreport, originally licensed under Apache License 2.0. Part of LoggerJSON.PlugTest are from Elixir's Plug licensed under Apache 2.

Copyright and License

Copyright (c) 2016 Nebo #15

Released under the MIT License, which can be found in LICENSE.md.

More Repositories

1

sage

A dependency-free tool to run distributed transactions in Elixir, inspired by Sagas pattern.
Elixir
894
star
2

annon.api

Configurable API gateway that acts as a reverse proxy with a plugin system.
Elixir
329
star
3

confex

Useful helper to read and use application configuration from environment variables.
Elixir
295
star
4

ecto_mnesia

Ecto adapter for Mnesia Erlang term database.
Elixir
240
star
5

gandalf.api

Open-Source Decision Engine and Scoring Table for Big-Data.
PHP
98
star
6

multiverse

Elixir package that allows to add compatibility layers via API gateways.
Elixir
93
star
7

ecto_trail

EctoTrail allows to store Ecto changeset changes in a separate audit_log table.
Elixir
54
star
8

gandalf.web

Open-Source Decision Engine and Scoring Table for Big-Data.
JavaScript
45
star
9

renew

Mix task to create mix projects that builds into Docker containers.
Elixir
33
star
10

mouth

Simple adapter based SMS sending library
Elixir
29
star
11

rbmq

Simple API for spawning RabbitMQ Producers and Consumers.
Elixir
22
star
12

gen_task

Generic Task behavior that helps encapsulate errors and recover from them in classic GenStage workers.
Elixir
22
star
13

k8s-utils

Kubernetes utils for debugging our development or production environments
Shell
20
star
14

ael.api

Media content storage access control system based on Signed URL's.
Elixir
18
star
15

ecto_paging

Cursor-based pagination for Ecto.
Elixir
14
star
16

annon.web

Annon API Gateway Dashboard - manage API Gateway settings, review and replay requests from history.
JavaScript
11
star
17

bsoneach

Elixir package that applies a function to each document in a BSON file.
Elixir
9
star
18

jvalid

Json Scheme validation helper, that allows to store schemes in a separate files.
Elixir
8
star
19

man.api

Template Rendering Engine as a Service
Elixir
6
star
20

annon.infra

Infrastructure helpers for Annon API Gateway.
Shell
6
star
21

postboy.api

Asynchronous delivery service for Email or SMS messages.
Elixir
4
star
22

alpine-cassandra

Cassandra in Alpine Linux box.
Shell
4
star
23

eview

Nebo #15 Views for our Elixir API applications.
Elixir
4
star
24

mithril.api

Authentication and role management service.
Elixir
4
star
25

react-nebo15-events

Event Manager for application on React JS
JavaScript
4
star
26

lumen-intercom

Intercom service for lumen
PHP
3
star
27

annon.ktl

`annonktl` is a Annon API Gateway management CLI.
Elixir
3
star
28

man.web

Mรกn Templates Rendering Service
JavaScript
3
star
29

react-nebo15-validate

Validation module for React application by Nebo15
JavaScript
3
star
30

alpine-php

Linux Alpine container with PHP 5.6/7 and Mongo driver.
Shell
2
star
31

lumen-mandrill

PHP
2
star
32

alpine-erlang

Erlang container based on Alpine Linux with Kubernetes support.
Dockerfile
2
star
33

alpine-elixir

Alpine Box with Elixir and Erlang installed.
Dockerfile
2
star
34

react-nebo15-components

React components
JavaScript
2
star
35

alpine-postgre

PostgreSQL Docker Images based on Alpine Linux and with the same API as official repo has.
Shell
2
star
36

annon.status.web

Annon API Gateway Status Page - see statuses of the APIs from Annon API Gateway.
JavaScript
1
star
37

egndf

gndf.io client for Elixir
Elixir
1
star
38

d3-structure

๐Ÿจ Build your d3-graphics with data structures and one entrypoint!
JavaScript
1
star
39

mbank.lib.angular-compiled

Compiled version for Angular MBank libruary
JavaScript
1
star
40

nebo-error-messages

JavaScript
1
star
41

alpine-mongodb

Alpine container with MongoDB
Shell
1
star
42

react-boilerplate

Boilerplate for React Univeral application, that is using Redux, React-router and Express
JavaScript
1
star
43

d3-builder

JavaScript
1
star
44

gulp-by-path

Transform files grouped by file.relative
JavaScript
1
star
45

lumen-rest

PHP
1
star
46

nebo-localize

JavaScript
1
star
47

drunken-russian

Tasks manager for PHP and MongoDB. 100% alcohol free.
PHP
1
star
48

oxygen

Deprecated. Use Elixir Registry instead of this package.
Elixir
1
star
49

onedayofmine.web

OneDayOfMine Project - it's our old and first unsupported startup, which we want to re-implement in future
PHP
1
star
50

url-parser

URL Parser module
JavaScript
1
star
51

alpine-fluentd-elasticsearch

Alpine Box with Fluentd and ElasticSearch plugin
1
star
52

nebo-validate

JavaScript
1
star
53

javascript-library-boilerplate

Javascript Library Boilerplate
1
star
54

react-nebo15-currency-input

React currency input by Nebo15
JavaScript
1
star
55

credits4all.web.admin

Playground based on Parse.com
CSS
1
star
56

tokenizer.api

Card Tokenization Service
Elixir
1
star
57

dogstat

Elixir client for StatsD servers.
Elixir
1
star
58

alpine-postgre-backup

Backup system for PostgreSQL containers.
Shell
1
star
59

ci-utils

Continuous Integration scripts for different languages
1
star