[Mono-list] Syslog Access

Jonathan Pryor jonpryor@vt.edu
Mon, 16 Aug 2004 21:56:09 -0400


On Mon, 2004-08-16 at 17:34, Clint Fairchild wrote:
> Is there a simple solution to access syslog with C#?  I'm attempting to
> write a daemon.

The answer should be System.Diagnostics.EventLog.  Alas, it isn't,
because no one has implemented a shim to make syslog look like a Windows
Event Log yet.  Sorry, it hasn't been a priority.

You'll have to P/Invoke syslog(3) directly.  Lucky you, I wrote a short
demo of "Hello, world" for syslog(3).  Unlucky you, I was lazy and used
the constant values in /usr/include/sys/syslog.h on Fedora Core 2.  This
should be good for Linux systems, but the constants will have different
values on other Unix platforms, so a "real" solution would mimic
Mono.Posix.

	// syslog example:
	using System;
	using System.Runtime.InteropServices;

	class Syslog_h {
		[Flags]
		public enum Option {
			Pid        = 0x01,
			Console    = 0x02,
			Delay      = 0x04,
			NoDelay    = 0x08,
			NoWait     = 0x10,
			PrintError = 0x20
		}

		[Flags]
		public enum Facility {
			Kernel   = 0 << 3,
			User     = 1 << 3,
			Mail     = 2 << 3,
			Daemon   = 3 << 3,
			Auth     = 4 << 3,
			Syslog   = 5 << 3,
			Lpr      = 6 << 3,
			News     = 7 << 3,
			Uucp     = 8 << 3,
			Cron     = 8 << 3,
			AuthPriv = 10 << 3,
			Ftp      = 11 << 3,
			Local0   = 16 << 3,
			Local1   = 17 << 3,
			Local2   = 18 << 3,
			Local3   = 19 << 3,
			Local4   = 20 << 3,
			Local5   = 21 << 3,
			Local6   = 22 << 3,
			Local7   = 23 << 3,
		}

		[Flags]
		public enum Level {
			Emerg   = 0,
			Alert   = 1,
			Crit    = 2,
			Err     = 3,
			Warning = 4,
			Notice  = 5,
			Info    = 6,
			Debug   = 7
		}

		// Note that `ident' is an IntPtr, not a string;
		// see Demo.Main() for why
		[DllImport ("libc")]
		public static extern void openlog (IntPtr ident, 
			Option option, Facility facility);

		[DllImport ("libc")]
		public static extern void syslog (int priority, 
			string message);

		[DllImport ("libc")]
		public static extern void closelog ();
	}

	class Demo {
		public static void Main (string[] args)
		{
			// Ident needs to be an IntPtr, not a string, 
			// as syslog doesn't copy the string; it 
			// assumes that the string won't change.  
			// Since strings are garbage collected, the
			// string will eventually be collected, causing
			// syslog(3) to print garbage for the ident
			// unless we make sure `ident' is allocated in
			// unmanaged memory:
			IntPtr ident = Marshal.StringToHGlobalAnsi (
				"this is my ident");
			Syslog_h.openlog (ident,
				Syslog_h.Option.Console | Syslog_h.Option.Pid |
					Syslog_h.Option.PrintError,
				Syslog_h.Facility.User);
			Syslog_h.syslog ((int) Syslog_h.Facility.User | 
				(int) Syslog_h.Level.Debug,
				"Hello, syslog!");
			Syslog_h.closelog ();
			Marshal.FreeHGlobal (ident);
		}
	}

 - Jon