Giter Site home page Giter Site logo

erlang-systemd's Introduction

systemd

Hex.pm HexDocs Hex.pm License GitHub Workflow Status Codecov

Simple library for notifying systemd about process state.

Features

  • NOTIFY_SOCKET is handled and You can notify supervisor about events happening in your application.
  • Watchdog process will be started automatically if enabled. It will also handle sending keep-alive messages automatically.
  • File descriptors fetching from the environment.
  • journal logger handler and formatters

Installation

Just add this to your rebar.config:

{deps, [systemd]}.

Or in case of Mix project, to your mix.exs:

defp deps do
  [
    {:systemd, "~> 0.2"}
  ]
end

Then call systemd:notify(ready) when your application is ready to work/accept connections.

Non-systemd systems

This application and all functions within are safe to call even in non-systemd and non-Linux OSes. In case if there is no systemd configuration options then all functions will simply work as (almost) no-ops.

Usage

Assuming you have my_app.service unit like that

[Unit]
Description=My Awesome App

[Service]
User=appuser
Group=appgroup
Type=notify
# Important! This need to run in foreground and not fork.
# Check documentation of your release tool.
ExecStart=/path/to/my_app start
WatchdogSec=10s
NotifyAccess=main
Restart=on-failure

[Install]
WantedBy=multi-user.target

(the Type=notify part is important)

You can inform systemd about state of your application. To do so just call:

systemd:notify(ready).

This will make systemctl start my_app.service to wait until application is up and running.

If you want to restart your application you can notify systemd about it with:

systemd:notify(reloading).

Message about application shutting down will be handled automatically for you.

For simplification of readiness notification there is systemd:ready() function that returns child specs for temporary process that can be used as a part of your supervision tree to mark the point when application is ready, ex.:

-module(my_app_sup).

-behaviour(supervisor).

-export([start_link/1,
         init/1]).

start_link(Opts) ->
    supervisor:start_link({local, ?MODULE}, ?MODULE, Opts).

init(_Opts) ->
    SupFlags = #{
      strategy => one_for_one
    },
    Children = [
      my_app_db:child_spec(),
      my_app_webserver:child_spec(),
      systemd:ready(),
      my_app_periodic_job:child_spec()
    ],

    {ok, {SupFlags, Children}}.

Logs

To handle logs you have 2 possible options:

  • Output data to standard output or error with special prefixes. This approach is much simpler and straightforward, however do not support structured logging and multiline messages.
  • Use datagram socket with special communication protocol. This requires a little bit more effort to set up, but seamlessly supports structured logging and multiline messages.

This library supports both formats, and it is up to You which one (or both?) your app will decide to use.

Standard error

There is systemd_kmsg_formatter which formats data using kmsg-like level prefixes can be used with any logger that outputs to standard output or standard error if this is attached to the journal. By default systemd library will update all handlers that use logger_std_h with type standard_io or standard_error that are attached to the journal (it is automatically detected via JOURNAL_STREAM environment variable). You can disable that behaviour by setting:

[
  {systemd, [{auto_formatter, false}]}
].

For custom loggers you can use this formatter by adding new option parent to the formatter options that will be used as "upstream" formatter, ex.:

logger:add_handler(example_handler, logger_disk_log_h, #{
  formatter => {systemd_kmsg_formatter, #{parent => logger_formatter,
                                          template => [msg]},
  config => #{
    file => "/var/log/my_app.log"
  }
}).

Datagram socket

This one requires systemd application to be started to spawn some processes required for handling sockets, so the best way to handle it is to add predefined systemd handlers after your application starts:

logger:add_handlers(systemd).

Be aware that this one is not guaranteed to work on non-systemd systems, so if You aren't sure if that application will be ran on systemd-enabled OS then you shouldn't use it as an only logger solution in your application or you can end with no logger attached at all.

This handler should not be used with systemd_kmsg_formatter as this will result with pointless kmsg-like prefixes in the log messages.

License

See LICENSE.

erlang-systemd's People

Contributors

hauleth avatar

Watchers

 avatar

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.