Include for writing to Eventlog/Syslog (Windows/Linux)

Applications, Games, Tools, User libs and useful stuff coded in PureBasic
User avatar
Didelphodon
PureBasic Expert
PureBasic Expert
Posts: 450
Joined: Sat Dec 18, 2004 11:56 am
Location: Vienna - Austria
Contact:

Include for writing to Eventlog/Syslog (Windows/Linux)

Post by Didelphodon »

Hi folks,

I use this (quickly written) code to log to Syslog on Linux and to Eventlog (Applications) under Windows.
Firstly you have to call the Init-Procedure to specify a name (ie program) ...

* Syslog_Init(applicationName.s = "")

... and then you can easily call the 3 variants ...

* Syslog_Info(Message$)
* Syslog_Warning(Message$)
* Syslog_Error(Message$)

May you have fun with this :-)

Cheers,
Didel.

Code: Select all

Global _Syslog_gl_ApplicationName.s = ""
Procedure Syslog_Init(applicationName.s = "")
	_Syslog_gl_ApplicationName = applicationName
EndProcedure
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
	Procedure _Syslog_Write2Log(constEventType.i, Message$)
		hdl.i = RegisterEventSource_(0, "chrisu")
		If (hdl)
			Dim s.s(0)
			s(0) = Message$
			ReportEvent_(hdl, constEventType, 0, 0, 0, 1, 0, @s(), 0)
			DeregisterEventSource_(hdl)
		EndIf
	EndProcedure
	Procedure Syslog_Info(Message$)
		_Syslog_Write2Log(4, Message$)
	EndProcedure
	Procedure Syslog_Warning(Message$)
		_Syslog_Write2Log(2, Message$)
	EndProcedure
	Procedure Syslog_Error(Message$)
		_Syslog_Write2Log(1, Message$)
	EndProcedure
CompilerElse
	Procedure _Syslog_Write2Log(level.s, Message$)
		If (FindString(Message$, Chr(10)))
			cnt.i = CountString(Message$, Chr(10))
			For i.i = 1 To cnt+1
				s.s = level + StringField(Message$, i, Chr(10))
				parms.s = "-t " + Chr(34) + ReplaceString(_Syslog_gl_ApplicationName, Chr(34), "'") + Chr(34) + " " + Chr(34) + ReplaceString(s, Chr(34), "'") + Chr(34)
				RunProgram("logger", parms, "", #PB_Program_Wait)
				level = Space(Len(level))
			Next i
		Else
			Message$ = level + Message$
			parms.s = "-t " + Chr(34) + ReplaceString(_Syslog_gl_ApplicationName, Chr(34), "'") + Chr(34) + " " + Chr(34) + ReplaceString(Message$, Chr(34), "'") + Chr(34)
			RunProgram("logger", parms, "", #PB_Program_Wait)
		EndIf
	EndProcedure
	Procedure Syslog_Info(Message$)
		_Syslog_Write2Log("Informational: ", Message$)
	EndProcedure
	Procedure Syslog_Warning(Message$)
		_Syslog_Write2Log("Warning: ", Message$)
	EndProcedure
	Procedure Syslog_Error(Message$)
		_Syslog_Write2Log("Error: ", Message$)
	EndProcedure
CompilerEndIf
; 
; Syslog_Init("chrisu-test")
; Syslog_Info("Hallo World!")
; Syslog_Info("Zeile 1" + Chr(10) + "Zeile 2" + Chr(10) + Chr(34) + "Hallo" + Chr(34))
Go, tell it on the mountains.
User avatar
Zebuddi123
Enthusiast
Enthusiast
Posts: 796
Joined: Wed Feb 01, 2012 3:30 pm
Location: Nottinghamshire UK
Contact:

Re: Include for writing to Eventlog/Syslog (Windows/Linux)

Post by Zebuddi123 »

Thanks for posting Didelphodon


tested works great will come in very handy :idea:

Zebuddi. :D
malleo, caput, bang. Ego, comprehendunt in tempore
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: Include for writing to Eventlog/Syslog (Windows/Linux)

Post by jassing »

While writing to the windows event log is a PITA (imho)writing to a syslog is easy, here's the routine I used when testing my (purebasic based) syslog server

NOTE: this has a windows api call (OutputDebugString) comment that out, and it should work regardless of OS (Don't forget to initialize the network sub-system)

Code: Select all

; SysLog CLIENT Function
; by Josh Assing (jAssing - josh@jAssing.com)
; v1.03

Enumeration
  #kernel_messages
  #user_level_messages
  #mail_system
  #System_daemons
  #security_authorization_messages
  #messages_generated_internally_by_syslogd
  #line_printer_subsystem
  #network_news_subsystem
  #UUCP_subsystem
  #clock_daemon
  #security_authorization_messages_2
  #FTP_daemon
  #NTP_subsystem
  #log_audit
  #log_alert
  #clock_daemon_2
  #local0
  #local1
  #local2
  #local3
  #local4
  #local5
  #local6
  #local7
EndEnumeration

Enumeration
  #Emergency     ; system is unusable
  #Alert         ; action must be taken immediately
  #Critical      ; critical conditions
  #Error         ; error conditions
  #Warning       ; warning conditions
  #Notice        ; normal but significant condition
  #Informational ; informational messages
  #Debug         ; Debug-level messages
EndEnumeration

Procedure.s GetSysLogRFCDate(nDate=-1)
	Protected cDate.s = ""
	Protected nMonth, cMonth.s
	If nDate = -1 : nDate = Date() : EndIf
	;Jan  2 16:29:26 
	nMonth = Month(nDate)
	If nMonth >0 And nMonth < 13
		Restore Months
		While nMonth
			Read.s cMonth.s 
			nMonth - 1
		Wend
	Else : cMonth = "<err>"
	EndIf
	
	cDate = cMonth+FormatDate(" %dd %hh:%ii:%ss",nDate)
	
	ProcedureReturn cDate
	
	DataSection
		Months:
		Data.s "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"
	EndDataSection
	
EndProcedure

Procedure SyslogClient(cMstText.s, cServer.s="127.0.0.1",nFacility.a=#local0, nSeverity.a=#Debug, cSource.s ="jSysLog")
  Protected Result = #False
  Protected h,cFullMessage.s, nLength, cPriority.s, nPort = 514
  
  If Val(StringField(cServer,2,":"))>0
  	nPort = Val(StringField(cServer,2,":"))
  EndIf
  
  cServer = StringField(cServer,1,":")
  
  If ((nFacility = 255 Or nFacility < 24) And nSeverity < 8) Or (nSeverity = 255 And nFacility>0 And nFacility<192)
    h = OpenNetworkConnection(cServer, nPort, #PB_Network_UDP)
    If h
    	If nFacility = 255
    		; do not include a facility
    		cFullMessage = ""	
    	Else
    		If nSeverity = 255
    			cPriority = StrU(nFacility,#PB_Byte)
    		Else
    			cPriority = StrU(nFacility << 3 + nSeverity, #PB_Byte) 
    		EndIf
    	
      	cFullMessage = "<" + cPriority + ">"
      EndIf
      
      cFullMessage = Trim(cFullMessage + GetSysLogRFCDate() + " "+GetComputerName()+" "+cSource)+" "+cMstText
      nLength = Len(cFullMessage)
      If SendNetworkData(h, @cFullMessage, nLength) = nLength
        Result = #True
      EndIf
      CloseNetworkConnection(h)
    EndIf
  EndIf
  
  If result : OutputDebugString_("Fwd'd message "+cFullMessage)
  Else : OutputDebugString_("Failed to fwd msg")
  EndIf	
  
  
  ProcedureReturn Result
  
EndProcedure
Note to use with a port # (Use IP:port# or FQDN:port#)

Code: Select all

if SyslogClient("This is a message to send", "SomeServer.com:331",#local0, #Debug, "My Program")
  ; Successfully sent
else ; Error Condition, send failed
endif
Post Reply