npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

daemonsauce

v0.3.11

Published

Just add Daemon Sauce to turn your app into a daemon.

Downloads

8

Readme

Daemon Sauce

Just add Daemon Sauce to your Node project, to make it a proper *nix daemon. This is intended to help build daemons that play nice on machines with services managed by something like (traditional) init(8) or Upstart.

The main things that this module does:

  • Handle the creation of a disconnected child process.
  • Manage a process lockfile.
  • Redirect console to an error log and to the syslog (depending on the method).
  • Setting user and group ids to drop privileges (when running as root).

Building and Installation

npm install daemonsauce

Or grab the source and

node-waf configure build

Note: This module contains native code, and so you will have to have a C compiler available. Consult your OS documentation for details on setting that up.

Testing

It is unfortunately not easy to put together a generic automated test for the functionality in this module, such that it can be expected to work in (that is, to successfully test) the wide range of environments in which it is potentially deployed. In practice, this module has been tested by a lot of trial and error, along with a fair amount of one-off poking and prodding.

The author would love some input (where "input" means "Pull requests, please!") on how to remedy this situation.

Usage

The easiest way to make use of this is by using the provided wrapper bin-script (in the examples directory). Arrange your application files so that the wrapper is in a bin directory, and next to bin is a directory containing your main application. Rename the wrapper script to have the same name as the main application directory. For example:

my-application/
    bin/
        server <-- the example bin-script
    server/
        package.json
        main.js
        ...

If you do this, then the script will take care of all the forking and setting of userids, and so on. It keys off of a few additional properties that can be defined in your package.json file:

  • rootMain -- If you define this to to be a file name (relative to the application directory), then it will be loaded and run (via require()) as the root userid (assuming the app started out running as root), just before Daemon Sauce drop privileges.

  • daemonUser -- Use this to specify the userid (by name) to run the main application as. If unset, it defaults to the product name (name in the package.json file.)

  • daemonGroup -- Use this to specify the groupid (by name) to run the main application as. If unset, it defaults to the userid (which may itself just be the default of the product name).

If you want to make life hard on yourself, there are also separate methods to handle most of the various bits and pieces. UTSL for details.

The one requirement for your commandline arguments is that you pass in a --daemon argument to kick things off. When running normally (that is, to cause it to create a real daemon in the usual fork/detach style), pass --daemon=parent. When running in a development environment, pass --daemon=foreground to cause the process to remain an attached foreground process (and not mess with log or lock files, either). If you are trying to debug what happens as the child process starts, make yourself a root shell (e.g., sudo su), and try running the daemon with --daemon=child. In the last case, note that the system will close and/or redirect stdio pretty early.

You should expect to see --daemon=child in the arguments to your application when it is running "for real" (as opposed to in one of the set-up phases).

Directory Setup Details

The suggested/example bin-script file assumes that a "normal" installation of a daemon is done in /usr/..., with associated data in /var/... (where the ...s are the same). When you install a daemon, it is probably a good idea to create that /var directory at the same time, assigning it a user and group that match the product name or explicit daemonUser / daemonGroup, as appropriate.

If the daemon is run from a directory that's not under /usr, it assumes it is in a development environment, and instead of looking for a var/... directory, it assumes that the data lives in a data subdirectory of the installation.

Logging Details

This section only applies when running as a daemon (as opposed to in the foreground for development).

Once set up, console.log() and most of the other standard logging functions will write to a file called error.log in the specified logging directory. The one exception is that console.info() will emit a log message to the syslog. (You can find the syslog in the file /var/log/messages on many Linux distros and in the file /var/log/system.log on OS X.)

Daemon Sauce also arranges to rotate the error.log file once a day (at around midnight UTC), renaming the file based on the date that it covered, and recreating / reopening the "plain" error.log to cover the upcoming day.

The idea behind all this is not that error.log or the syslog are great places to log to, but rather they are acceptable places to log to as a fallback, when it is too early in a daemon's life to have anything more durable or structured to use. It is also the case that Node (in 0.6.*, as of this writing) will always write "uncaught exception" messages to the underlying stderr stream, as the process is dying. At least error.log is a place where these messages can be found, when doing forensics.

Lockfile Details

This section only applies when running as a daemon (as opposed to in the foreground for development).

A lockfile is used to ensure that only one instance of a daemon is running at any given time.

In this case, the lockfile is named product-name.pid and placed in the specified run directory. During startup, if it turns out that another process has locked the lockfile (this uses the POSIX call lockf()), this will cause the new process to exit after writing a message to that effect to the syslog.

If the lock is successful, then the "winning" process writes out its process id to the lockfile, which makes it convenient to inspect, e.g. by cat product-name.pid from a console.

Using Upstart

The file upstart.conf in the example directory is a simple example of how one might hook up a service that uses Daemon Sauce.

To Do

  • Find something to do!

Contributing

Questions, comments, bug reports, and pull requests are all welcome. Submit them at the project on GitHub.

Bug reports that include steps-to-reproduce (including code) are the best. Even better, make them in the form of pull requests that add tests (which, yes, is a hard nut to crack in this case). Thanks!

Author

Dan Bornstein (personal website), supported by The Obvious Corporation.

License

Copyright 2012 The Obvious Corporation.

Licensed under the Apache License, Version 2.0. See the top-level file LICENSE.txt and (http://www.apache.org/licenses/LICENSE-2.0).