A small procedure to send syslog messages (with program)

Share your advanced PureBasic knowledge/code with the community.
infratec
Always Here
Always Here
Posts: 7582
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

A small procedure to send syslog messages (with program)

Post by infratec »

Hi,

since I want to generate syslog messages, I wrote a small procedure for it.
It is not 100% RFC conform, since at least the version ("1 ") should be inside,
but it looks not nice in linux /var/log/messages, and so I commented it out.

It works in Windo.. and in Linux. And it should work on Mac.

Code: Select all

CompilerIf #PB_Compiler_IsMainFile
  EnableExplicit
CompilerEndIf


#Version = "1.10"


Enumeration Severity
  #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


Enumeration Facility
  #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


Procedure Syslog(Server$, Text$, Severity.a, Facility.a=#local0, Port.i=514)
  
  Protected Result.i, Con.i, Msg$
  
  
  If Facility < 24 And Severity < 8
    
    Con = OpenNetworkConnection(Server$, Port, #PB_Network_UDP)
    If Con
      Msg$ = "<" + StrU(Facility << 3 | Severity, #PB_Byte) + ">"
      ;Msg$ + "1 "
      ;Msg$ + FormatDate("%yyyy-%mm-%ddT%hh:%ii:%ss.000Z ", Date())
      Msg$ + GetFilePart(ProgramFilename(), #PB_FileSystem_NoExtension) + ": "
      Msg$ + Text$
      If SendNetworkString(Con, Msg$) = StringByteLength(Msg$, #PB_UTF8)
        Result = #True
      EndIf
      CloseNetworkConnection(Con)
    EndIf
  EndIf
  
  ProcedureReturn Result
  
EndProcedure



CompilerIf #PB_Compiler_IsMainFile
  
  Procedure Usage()
    
    PrintN("")
    PrintN(" Syslog V" + #VERSION)
    PrintN("")
    PrintN(" usage: syslog server message [severity [facility]] [-v]")
    PrintN("")
    PrintN("  server  : name or IP address of the syslog server")
    PrintN("  message : the message to send")
    PrintN("  severity: level of the message (0..7) default is 6 (informational)")
    PrintN("  facility: facility of the sender (0..24) default is 16 (local0)")
    PrintN("  -v      : increase verbosity")
    PrintN("")
    PrintN(" example: syslog 192.168.0.1 " + #DQUOTE$ + "This is a test" + #DQUOTE$)
    PrintN("")
    
    End 1
    
  EndProcedure
  
  
  
  
  Define Severity.i, Facility.i, Verbose.i, Server$, Msg$, Index.i, i.i, Result.i
  
  
  If OpenConsole()
    
    If CountProgramParameters() < 2 : Usage() : EndIf
    
    Severity = #Informational
    Facility = #local0
    
    Server$ = ProgramParameter(0)
    Msg$ = ProgramParameter(1)
    
    
    For i = 2 To CountProgramParameters() - 1
      If ProgramParameter(i) = "-v"
        Verbose + 1
      Else
        Select Index
          Case 0
            Severity = Val(ProgramParameter(i))
            If Severity < #Emergency Or Severity > #Debug
              Severity = #Informational
            EndIf
            Index + 1
          Case 1
            Facility = Val(ProgramParameter(i))
            If Facility < #kernel_messages Or Facility > #local7
              Facility = #local0
            EndIf
            Index + 1
        EndSelect
      EndIf
    Next i
    
    CompilerIf #PB_Compiler_Version < 610
      If InitNetwork()
      CompilerEndIf
      
      If Verbose
        PrintN("")
        PrintN(" Server  : " + Server$)
        PrintN(" Severity: " + Str(Severity))
        PrintN(" Facility: " + Str(Facility))
        PrintN(" Message : " + Msg$)
        PrintN("")
      EndIf
      
      Result = Syslog(Server$, Msg$, Severity, Facility)
      
      If Verbose
        If Result
          PrintN(" message transmitted")
        Else
          PrintN(" an error occured")
        EndIf
        PrintN("")
      EndIf
      CompilerIf #PB_Compiler_Version < 610  
      Else
        PrintN("")
        PrintN("was not able to initialize the network")
      EndIf
    CompilerEndIf
    
  EndIf
  
  End Result
  
CompilerEndIf
Have fun.

Bernd

P.S.: to receive syslog messages in windo.. I use the great tftpd32
Last edited by infratec on Thu Sep 12, 2024 9:58 am, edited 4 times in total.
univeda
User
User
Posts: 22
Joined: Wed May 13, 2009 12:40 am
Location: Germany

Re: A small procedure to send syslog messages (with program)

Post by univeda »

Just found your code while searching for a syslog-possibility in purebasic.

Works great for me. Thank you!

Michael
PB 4.41 Windows x86

Projects: ExTSC - Extended Terminal Services Client | Univeda - Universal Knowledgebase - Dungeon - paused 2D RPG
infratec
Always Here
Always Here
Posts: 7582
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: A small procedure to send syslog messages (with program)

Post by infratec »

Hi Michael,

thanks for your reply.
So I know now that it was at least helpful for one other person. :D

Greetings to Sol...

Bernd
highend
Enthusiast
Enthusiast
Posts: 162
Joined: Tue Jun 17, 2014 4:49 pm

Re: A small procedure to send syslog messages (with program)

Post by highend »

Tried this today (I know this is an old thread...)

Downloaded and run Tftpd64

Compiled the source code (commented out the two lines regarding InitNetwork()) and ran it with:
"Debug to syslog.exe" 192.168.0.60 "this is a test"

That ip is the same I'm running the .exe on but using 127.0.0.1 won't change the output...

The Tftpd64 server logs the event but all it displays for the text that was send is: <

Does it need changes to run correctly on v6.11 / 12 Beta?
PeDe
Enthusiast
Enthusiast
Posts: 278
Joined: Sun Nov 26, 2017 3:13 pm

Re: A small procedure to send syslog messages (with program)

Post by PeDe »

Can you change the line

If SendNetworkData(Con, @Msg$, Length) = Length

to

If SendNetworkString(Con, Msg$, #PB_UTF8) = Length

Otherwise, Unicode data is sent and only the first character is displayed.

Peter
highend
Enthusiast
Enthusiast
Posts: 162
Joined: Tue Jun 17, 2014 4:49 pm

Re: A small procedure to send syslog messages (with program)

Post by highend »

Thank you, PeDe!

This fix solves the issue, it now works as expected :mrgreen:
infratec
Always Here
Always Here
Posts: 7582
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: A small procedure to send syslog messages (with program)

Post by infratec »

Hm... then it is a bug, because UTF8 is the default according to the help.
But I can cannot test it at the moment.
infratec
Always Here
Always Here
Posts: 7582
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: A small procedure to send syslog messages (with program)

Post by infratec »

But the code needs an update. I will do it asap.
infratec
Always Here
Always Here
Posts: 7582
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: A small procedure to send syslog messages (with program)

Post by infratec »

Updated the code above.
Quin
Addict
Addict
Posts: 1127
Joined: Thu Mar 31, 2022 7:03 pm
Location: Colorado, United States
Contact:

Re: A small procedure to send syslog messages (with program)

Post by Quin »

infratec wrote: Thu Sep 12, 2024 8:07 am Hm... then it is a bug, because UTF8 is the default according to the help.
But I can cannot test it at the moment.
Not a bug, the three parameters are Connection, String$, and Format. The code was initially passing the length as format.
Post Reply