Coder Social home page Coder Social logo

structlog.nvim's Introduction

structlog.nvim

Luarocks - structlog.nvim GitHub tag License

test sanitize Documentation

Structured Logging for nvim, using Lua

demo

Why using it

structlog makes logging in Lua less painful and more powerful by adding structure to your log entries.

Instead of writting complex messages, you can start thinking in terms of an event that happens in the context of key/value pairs.
Each log entry is a meaningful dictionary instead of an opaque string!

Thanks to its flexible design, the structure of the final log output is up for you to decide.
Each log entry goes through a processor pipeline that is just a chain of functions that receive a dictionary and return a new dictionary that gets fed into the next function. That allows for simple but powerful data manipulation.
This dictionary is then formatted and sent out to the sink.

structlog-banner drawio

For more details, consider reading the documentation.

Installation

Using packer.nvim

use { "Tastyep/structlog.nvim" }

Using luarocks

luarocks install --local structlog.nvim

Design

As explained in the introduction, log messages go through a pipeline to provide common information and to structure them into a comprehensible format. Internally, the log message is a dictionary built by the logger and is composed as follow:

  local log = {
    level = Level.name(level), -- The log level represented as a string
    msg = msg,                 -- The given message
    logger_name = logger.name, -- The name of the logger
    events = events or {},     -- The dictionary containing the 'key=value' arguments
  }

At the end of a pipeline, the message msg field should contain the text to write to the sink.

Processors

Processors are functions with the goal of enriching log messages. These functions accept one parameter, log which they edit by adding new key=value pairs, such as the logger's name or the current timestamp, and return it on completion.

See the processors documentation.

Formatters

Formatters define the structure of the log. By default vim.inspect is used to format the given arguments events as key=value pairs. All formatters have the same interface. They expose a formatting function accepting a dictionary log and return that same dictionary, modified so that log.msg contains the message to write to the sink.

See the formatters documentation.

Sinks

Sinks specify where to write the log message. Like the other elements of the pipeline, sinks accept log as parameter.

See the sinks documentation.

Usage

Minimal

local log = require("structlog")

log.configure({
  my_logger = {
    pipelines = {
      {
        log.level.INFO,
        {
          log.processors.Timestamper("%H:%M:%S"),
        },
        log.formatters.Format( --
          "%s [%s] %s: %-30s",
          { "timestamp", "level", "logger_name", "msg" },
        ),
        log.sinks.Console(),
      },
    },
  },
  other_logger = {
    pipelines = { ... }
  },
})

local logger = log.get_logger("my_logger")

Complete

local log = require("structlog")

log.configure({
  my_logger = {
    pipelines = {
      {
        level = log.level.INFO,
        processors = {
          log.processors.StackWriter({ "line", "file" }, { max_parents = 0, stack_level = 0 }),
          log.processors.Timestamper("%H:%M:%S"),
        },
        formatter = log.formatters.FormatColorizer( --
          "%s [%s] %s: %-30s",
          { "timestamp", "level", "logger_name", "msg" },
          { level = log.formatters.FormatColorizer.color_level() }
        ),
        sink = log.sinks.Console(),
      },
      {
        level = log.level.WARN,
        processors = {},
        formatter = log.formatters.Format( --
          "%s",
          { "msg" },
          { blacklist = { "level", "logger_name" } }
        ),
        sink =  log.sinks.NvimNotify(),
      },
      {
        level = log.level.TRACE,
        processors = {
          log.processors.StackWriter({ "line", "file" }, { max_parents = 3 }),
          log.processors.Timestamper("%H:%M:%S"),
        },
        formatter = log.formatters.Format( --
          "%s [%s] %s: %-30s",
          { "timestamp", "level", "logger_name", "msg" }
        ),
        sink = log.sinks.File("./test.log"),
      },
    },
  },
  },
  -- other_logger = {...}
})

local logger = log.get_logger("my_logger")
logger:info("A log message")
logger:warn("A log message with keyword arguments", { warning = "something happened" })
cat test.log:
10:43:23 [INFO] my_logger: A log message                            file="lua/foo/bar.lua", line=9
10:43:23 [WARN] my_logger: A log message with keyword arguments     file="lua/foo/bar.lua", line=10, warning="something happened"

notify

structlog.nvim's People

Contributors

tastyep avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

structlog.nvim's Issues

Please, provide documentation about the timestamp format

Hello, thanks for the library.

Can you provide more details about the accepted format by the Timestamper? This is all what the docs say:

Timestamper (format)
Add a timestamp entry.
Parameters:
format How to format the timestamp

I want to add Date and time to the format

question: integration into a plugin

Hi,

i want to integrate your wonderful logging tool as optional dependency into aserowy/tmux.nvim. The point is, i have a REALLY light integration for logging and could define a new channel at https://github.com/aserowy/tmux.nvim/tree/main/lua/tmux/log. Thus, the user must configure it proactively to use your logging implementation.
But it would be cool, to just check if your plugin is present and if so, register the channel automatically. Do you have any idea how i can check if your plugin exists (and is loaded) to register all log calls against it?

Kind regards
Alexander

Console colors are not permanent

Using the FormatColorizer sink, outputted colors are not permanent.
When entering :messages the colors are not present anymore.

This is probably because of vim.api.nvim_echo.
A combination of echohl and echom isn't possible because the latter automatically adds a newline and multiple calls need to be done

Console sink class in the docs takes 2 parameters, `level` and `opts` but in the Console class code, it only takes one parameter, `opts`

I'm sorry if I'm missing something, but as I was updating my config to use Lazy instead of Packer, I encountered the error:

E5108: Error executing lua ...nvim/lazy/structlog.nvim/lua/structlog/sinks/console.lua:25: attempt to index local 'opts' (a number value)                                                                
stack traceback:
        ...nvim/lazy/structlog.nvim/lua/structlog/sinks/console.lua:25: in function 'Console'
        [string ":lua"]:1: in main chunk

After some blind debugging, I realized passing the Log level number is what causes it and after further checking is when i found the Console class:

function Console:new(opts)
  opts = opts or {}

  local console = {}

  console.async = opts.async or true -- Line 25
  console.processors = opts.processors or {}
  console.formatter = opts.formatter or KeyValue()

  Console.__index = Console
  setmetatable(console, self)

  return console
end

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.