Ben Godfrey

Running an Erlang release as a Windows service

I’ve been writing a monitoring tool similar to Munin or collectd in Erlang — Rolf. Erlang is a natural fit for the problem. My system has a lot less code than others, because Erlang gives me so much of what is required — distributed messaging, multiprocessing, fault tolerance and much more. I’m using rebar to package my app as an Erlang application and generate releases to distribute.

The Windows distributions of Erlang provides the program erlsrv.exe to create and manage Windows services which host Erlang apps. The manual page is pretty opaque and there aren’t a lot of examples of erlsrv’s usage on the web, with the notable exception of RabbitMQ’s rabbitmq-server.bat. RabbitMQ doesn’t use Erlang’s release system. This can be done, but there are a few extra arguments that need to be specified.

The command I’m currently using to install Rolf as a service is:

c:\erl5.8.3\erts-5.8.3\bin\erlsrv.exe add Rolf -c "Collects system data for monitoring." -w c:\rolf -m c:\erl5.8.3\erts-5.8.3\bin\start_erl.exe -debugtype reuse -args "-setcookie rolf123 ++ -reldir c:\rolf\releases"

Let’s go through these arguments one by one:

  • Erlang R14B02 is installed in c:\erl5.8.3 and the Rolf release generated by rebar is in c:\rolf.
  • add Rolf: Specify that we’re adding a new service called “Rolf.”
  • -c: Service description.
  • -w: Working directory. Any files paths used by your program will be relative to this dir. The default working directory for services is the Windows system directory, so it’s worth specifying something more sane.
  • -m: Specify the “Erlang machine” — the program that will be used to start a VM. start_erl.exe starts an embedded VM, equivalent to a Unix daemon in.
  • -debugtype reuse: When the service runs, a file called <servicename>.debug is created in the working directory. This option tells the Erlang VM to reuse that log file, rather than clobbering it each time the service starts.
  • -args: Specify additional Erlang VM options.

The directory path passed to -reldir should be the releases sub-directory containing start_erl.data (c:\rolf\releases in my case).

Make sure you have the same version of erts on the machine on which you generate the release and the one on which you run it. start_erl.exe isn’t very clever about multiple versions, producing errors like “Could not open registry key.” The source for start_erl.exe is the best place to go for more info on how that works.

Note I haven’t specified the -name parameter. I tried -sname rolf, -sname rolf@%COMPUTERNAME% and -name rolf. My service always crashed with the error “Erlang machine stopped instantly (distribution name conflict?)”.

Comments

Add a new comment

Comments are closed for this post.