Re: rawlog data in a lua script
Hi Aki, On 08.08.22 13:54, Aki Tuomi wrote: Hi, Michael, did you consider my suggestion to use raw events instead of rawlogs for this? I was writing an answer to you next :-) As far as I can see, the "Event Export" only exports events of the requests, but not the full raw responses, correct? https://doc.dovecot.org/configuration_manual/event_export/ I need the complete rawlog that currently is written to the rawlog directory, which means the raw requests (IMAP, POP3 commands), and the raw response lines (for example a FETCH response -> a 20 MB mail content). Everything that could be seen on the wire via tcpdump after authentication (which is the rawlog of Dovecot as far as I can see). I need the rawlog feature, but not written to multiple files (which I have to collect in realtime with some black magic), but for example in a lua-script, which would make it a lot easier to analyse and/or send it to an HTTP endpoint. Maybe there are other possibilities, for example sending the rawlog of a user to a single file (or pipe/socket), where I can easily receive the raw logs for that user and send it to an HTTP endpoint. That's a lot easier than to "watch" a directory for new files, detect changes to existing files, collect them and send them via HTTP. I somehow need to send the raw log of specific users in realtime (maybe with a few seconds delay) to an HTTP endpoint (where each request or response is a single HTTP request, maybe we could also batch some requests and responses to reduce the HTTP requests to the endpoint). The current implementation of the rawlog feature is nice for manually debugging a single user, but when debugging/monitoring multiple users automatically, collect the logs and send them to a central place, it's hard to use ("watching" directories for changes via inotify, and run "tail" on the files for hours and days is not fun and can easily break). Michael On 08/08/2022 14:52 eestmichael.z...@feierfighter.de wrote: Hi, as far as I know I cannot configure Dovecot to pipe the rawlog into rsyslog. Or can I, how? The rawlog feature in Dovecot writes multiple files (two for each connection, one for raw requests and one for raw responses) into a predefined directory for the user. This generates dozens or hundreds of files per user per day, each file with a timestamp in it, so the filename is not predictable. Even if it works, I'm not sure if syslog (rsyslog or syslog-ng) should be (ab)used to collect the rawlog file contents, which might be hundreds of MB per minute if someone FETCHes all his emails while setting up a new account in Thunderbird or so. That sounds like a suboptional idea. Syslog cannot handle binary text I guess, and it might have limits like "line length limits" or similar. It sounds like the wrong tool for the job. Michael Am 28-Jul-2022 15:28:16 +0200 schriebdove...@ptld.com: I'm searching for a possibility to have the rawlog feature in lua, which would be much easier for processing. It would be much easier to hook to the "raw request and response events" inside Dovecot and have the rawlog-data in a lua script, where I can prepare it and send it to another maschine for monitoring/collection/analysis/statistics or similar, for example via HTTP. rsyslog has this feature (omprog) allowing you to setup any script/program for it to pipe logs to in real time. https://www.rsyslog.com/doc/master/configuration/modules/omprog.html https://github.com/rsyslog/rsyslog/blob/master/plugins/external/INTERFACE.md Works similar in concept to postfix policy servers if you are familiar with them.
Re: rawlog data in a lua script
Hi, Michael, did you consider my suggestion to use raw events instead of rawlogs for this? Aki > On 08/08/2022 14:52 EEST michael.z...@feierfighter.de wrote: > > > Hi, > > as far as I know I cannot configure Dovecot to pipe the rawlog into rsyslog. > Or can I, how? > > The rawlog feature in Dovecot writes multiple files (two for each connection, > one for raw requests and one for raw responses) into a predefined directory > for the user. This generates dozens or hundreds of files per user per day, > each file with a timestamp in it, so the filename is not predictable. > > Even if it works, I'm not sure if syslog (rsyslog or syslog-ng) should be > (ab)used to collect the rawlog file contents, which might be hundreds of MB > per minute if someone FETCHes all his emails while setting up a new account > in Thunderbird or so. That sounds like a suboptional idea. Syslog cannot > handle binary text I guess, and it might have limits like "line length > limits" or similar. It sounds like the wrong tool for the job. > > Michael > > > Am 28-Jul-2022 15:28:16 +0200 schrieb dove...@ptld.com: > > > I'm searching for a possibility to have the rawlog feature in lua, which > > > would be much easier for processing. > > > > > > It would be much easier to hook to the "raw request and response events" > > > inside Dovecot and have the rawlog-data in a lua script, > > > where I can prepare it and send it to another maschine for > > > monitoring/collection/analysis/statistics or similar, for example via > > > HTTP. > > > > > > rsyslog has this feature (omprog) allowing you to setup any script/program > > for it to pipe logs to in real time. > > > > https://www.rsyslog.com/doc/master/configuration/modules/omprog.html > > https://github.com/rsyslog/rsyslog/blob/master/plugins/external/INTERFACE.md > > > > Works similar in concept to postfix policy servers if you are familiar with > > them.
Re: rawlog data in a lua script
Hi, as far as I know I cannot configure Dovecot to pipe the rawlog into rsyslog. Or can I, how? The rawlog feature in Dovecot writes multiple files (two for each connection, one for raw requests and one for raw responses) into a predefined directory for the user. This generates dozens or hundreds of files per user per day, each file with a timestamp in it, so the filename is not predictable. Even if it works, I'm not sure if syslog (rsyslog or syslog-ng) should be (ab)used to collect the rawlog file contents, which might be hundreds of MB per minute if someone FETCHes all his emails while setting up a new account in Thunderbird or so. That sounds like a suboptional idea. Syslog cannot handle binary text I guess, and it might have limits like "line length limits" or similar. It sounds like the wrong tool for the job. Michael Am 28-Jul-2022 15:28:16 +0200 schrieb dove...@ptld.com: > I'm searching for a possibility to have the rawlog feature in lua, which > would be much easier for processing. > > It would be much easier to hook to the "raw request and response events" > inside Dovecot and have the rawlog-data in a lua script, > where I can prepare it and send it to another maschine for > monitoring/collection/analysis/statistics or similar, for example via HTTP. rsyslog has this feature (omprog) allowing you to setup any script/program for it to pipe logs to in real time. https://www.rsyslog.com/doc/master/configuration/modules/omprog.html https://github.com/rsyslog/rsyslog/blob/master/plugins/external/INTERFACE.md Works similar in concept to postfix policy servers if you are familiar with them.
Re: rawlog data in a lua script
Hi Paul, I don't understand how to use your idea/script together with the rawlog feature of Dovecot. The rawlog feature in Dovecot writes multiple files (two for each connection, one for raw requests and one for raw responses) into a predefined directory for the user. This generates dozens or hundreds of files per user per day, each file with a timestamp in it, so the filename is not predictable. How should I create "a socket" for that to capture the file contents if I don't know the filenames that will be used? Michael Am 28-Jul-2022 13:02:16 +0200 schrieb p...@scom.ca: Hi - I use this python script to capture a socket (ie the log file) and then send it to syslog, i use this for all the systems that do not really support syslogging (apache etc) basic useage /usr/bin/nohup /programs/common/capture -s /usr/local/apache2/logs/httpd-access.log -l httpd -d 10.228.0.6:514 -p httpd & > /dev/null i typically run this at startup in rc.local hope this helps
Re: rawlog data in a lua script
On 28 July 2022 13.38.17 UTC, "João Silva" wrote: >Thanks a lot for this thread. > >I was starting to plan a system where multiples processes can write to a file >and completely forgot that syslog is designed to do that. > >It is a perfect solution, I only had to configure a local facility to receive >the data and add 3 lines of code to the program (including the import). > >On 28/07/2022 12:01, Paul Kudla (SCOM.CA Internet Services Inc.) wrote: >> >> Hi - I use this python script to capture a socket (ie the log file) and then >> send it to syslog, i use this for all the systems that do not really support >> syslogging (apache etc) >> >> basic useage >> >> /usr/bin/nohup /programs/common/capture -s >> /usr/local/apache2/logs/httpd-access.log -l httpd -d 10.228.0.6:514 -p httpd >> & > /dev/null >> >> i typically run this at startup in rc.local >> On 7/28/2022 6:17 AM, dovecot-boun...@dovecot.org wrote: >>> Hi, >>> I'm searching for a possibility to have the rawlog feature in lua, which >>> would be much easier for processing. Currently Dovecot, when activating >>> rawlog for a user, writes everything to disk (which creates I/O), and I >>> have to somehow read it from there. That's a bit complicated, because I >>> have to get notified via inotify or similar when there are new files >>> created, and then I have to start a "tail" or "epoll" mechanism on the >>> files to get the contents in more or less real time (IMAP sessions can be >>> multiple hours or days). >>> It would be much easier to hook to the "raw request and response events" >>> inside Dovecot and have the rawlog-data in a lua script, where I can >>> prepare it and send it to another maschine for >>> monitoring/collection/analysis/statistics or similar, for example via HTTP. >>> Having the rawlog data available in lua would make things a lot easier. >>> Is there any possibility at the moment to create a lua script and "hook" to >>> those "request and response events"? If not, would it be possible to add >>> that feature in the future? >>> Kind regards >>> Michael If you are only interested in IMAP commands you can use event exporter to send individual commands preparsed in json format to HTTP endpoint. Aki
Re: rawlog data in a lua script
Thanks a lot for this thread. I was starting to plan a system where multiples processes can write to a file and completely forgot that syslog is designed to do that. It is a perfect solution, I only had to configure a local facility to receive the data and add 3 lines of code to the program (including the import). On 28/07/2022 12:01, Paul Kudla (SCOM.CA Internet Services Inc.) wrote: Hi - I use this python script to capture a socket (ie the log file) and then send it to syslog, i use this for all the systems that do not really support syslogging (apache etc) basic useage /usr/bin/nohup /programs/common/capture -s /usr/local/apache2/logs/httpd-access.log -l httpd -d 10.228.0.6:514 -p httpd & > /dev/null i typically run this at startup in rc.local hope this helps : -- ## cat capture #!/usr/local/bin/python3 # -*- coding: UTF-8 -*- import os,sys,socket import datetime,time from optparse import OptionParser from lib import * USAGE_TEXT = '''\ usage: %%prog %s[options] ''' parser = OptionParser(usage=USAGE_TEXT % '', version='0.4') parser.add_option("-s", "--socket", dest="socket_file", help="Socket File to Capture") parser.add_option("-l", "--label", dest="label", help="Syslog Label to Insert") parser.add_option("-d", "--destination", dest="destination", help="Syslog Destibnation Server:Port") parser.add_option("-p", "--pid", dest="pid", help="PID Process Name") #parser.add_option("-e", "--email", dest="email", help="Additional Email To") #parser.add_option("-t", "--temp", dest="tempdir", help="Local Temp Directory") options, args = parser.parse_args() print (options.socket_file) print (options.label) print (options.destination) print (options.pid) if options.socket_file == None : print ('Missing Socket File Information') sys.exit() if options.label == None : print ('Missing Syslog Label Information') sys.exit() if options.destination == None : print ('Missing Syslog Destination host:[port]') sys.exit() if options.pid == None : print ('Missing Syslog Pid Process Name') sys.exit() #try local syslog (/var/run/log) UDP_IP = options.destination.split(':') if len(UDP_IP) == 2 : #Set Port UDP_PORT = int(UDP_IP[1]) else : UDP_PORT = 514 #Default UDP_IP = UDP_IP[0] #Server #MESSAGE = str("<22>Mar 27 04:16:16 es-scom[12345] offsite.scom.ca su: Hello, World!") #MESSAGE = str("<183>Mar 27 16:17:41 scom-live[72178]: Hello World") print("UDP target IP: %s" % UDP_IP) print("UDP target port: %s" % UDP_PORT) #print("message: %s" % MESSAGE) count = 10 #sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #sock.sendto(MESSAGE, (UDP_IP, UDP_PORT)) #sock.sendto(bytes(MESSAGE, "utf-8"), (UDP_IP, UDP_PORT)) #sock.close() #sys.exit() #def read_commands(): try: print ("Creating read pipe... %s" %options.socket_file ) os.mkfifo(options.socket_file) # Create pipe print ("Pipe %s created!" %options.socket_file ) except: print ("Pipe %s already exists" %options.socket_file ) #chmod 777 the file so everyone can talk to it os.system('/bin/chmod 777 %s' %options.socket_file) with open(options.socket_file, "r") as pipecmd: while True: time.sleep(.001) try: line = pipecmd.readline() if line != '' : #New Data if line == '\n' : continue print ('Raw Text : %s' %line) encoded_string = line.encode("ascii", "ignore") line = encoded_string.decode() line = create_ascii(line) line = line.ascii print ('Line after ASCII : %s' %line) print ( 'Line Count : %s' %len(line) ) #line = data #go get my pid pid_process = '0' if options.pid == 'postfix' : #its a diverted postfix process get the actual pid from raw text pid_process = line.split('[',1)[1].split(']',1)[0] else : command = commands('/bin/ps -axww | /usr/bin/grep %s' %options.pid) print () #print (command.output) for n in range (0,len(command.output)) : if '/bin/ps -axww | /usr/bin/grep' not in command.output[n] and '/usr/bin/grep' not in command.output[n] and '/usr/local/bin/python3' not in command.output[n] : pid_process = ( command.output.spli
Re: rawlog data in a lua script
> I'm searching for a possibility to have the rawlog feature in lua, which > would be much easier for processing. > > It would be much easier to hook to the "raw request and response events" > inside Dovecot and have the rawlog-data in a lua script, > where I can prepare it and send it to another maschine for > monitoring/collection/analysis/statistics or similar, for example via HTTP. rsyslog has this feature (omprog) allowing you to setup any script/program for it to pipe logs to in real time. https://www.rsyslog.com/doc/master/configuration/modules/omprog.html https://github.com/rsyslog/rsyslog/blob/master/plugins/external/INTERFACE.md Works similar in concept to postfix policy servers if you are familiar with them.
Re: rawlog data in a lua script
Hi - I use this python script to capture a socket (ie the log file) and then send it to syslog, i use this for all the systems that do not really support syslogging (apache etc) basic useage /usr/bin/nohup /programs/common/capture -s /usr/local/apache2/logs/httpd-access.log -l httpd -d 10.228.0.6:514 -p httpd & > /dev/null i typically run this at startup in rc.local hope this helps : -- ## cat capture #!/usr/local/bin/python3 # -*- coding: UTF-8 -*- import os,sys,socket import datetime,time from optparse import OptionParser from lib import * USAGE_TEXT = '''\ usage: %%prog %s[options] ''' parser = OptionParser(usage=USAGE_TEXT % '', version='0.4') parser.add_option("-s", "--socket", dest="socket_file", help="Socket File to Capture") parser.add_option("-l", "--label", dest="label", help="Syslog Label to Insert") parser.add_option("-d", "--destination", dest="destination", help="Syslog Destibnation Server:Port") parser.add_option("-p", "--pid", dest="pid", help="PID Process Name") #parser.add_option("-e", "--email", dest="email", help="Additional Email To") #parser.add_option("-t", "--temp", dest="tempdir", help="Local Temp Directory") options, args = parser.parse_args() print (options.socket_file) print (options.label) print (options.destination) print (options.pid) if options.socket_file == None : print ('Missing Socket File Information') sys.exit() if options.label == None : print ('Missing Syslog Label Information') sys.exit() if options.destination == None : print ('Missing Syslog Destination host:[port]') sys.exit() if options.pid == None : print ('Missing Syslog Pid Process Name') sys.exit() #try local syslog (/var/run/log) UDP_IP = options.destination.split(':') if len(UDP_IP) == 2 : #Set Port UDP_PORT = int(UDP_IP[1]) else : UDP_PORT = 514 #Default UDP_IP = UDP_IP[0] #Server #MESSAGE = str("<22>Mar 27 04:16:16 es-scom[12345] offsite.scom.ca su: Hello, World!") #MESSAGE = str("<183>Mar 27 16:17:41 scom-live[72178]: Hello World") print("UDP target IP: %s" % UDP_IP) print("UDP target port: %s" % UDP_PORT) #print("message: %s" % MESSAGE) count = 10 #sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) #sock.sendto(MESSAGE, (UDP_IP, UDP_PORT)) #sock.sendto(bytes(MESSAGE, "utf-8"), (UDP_IP, UDP_PORT)) #sock.close() #sys.exit() #def read_commands(): try: print ("Creating read pipe... %s" %options.socket_file ) os.mkfifo(options.socket_file)# Create pipe print ("Pipe %s created!" %options.socket_file ) except: print ("Pipe %s already exists" %options.socket_file ) #chmod 777 the file so everyone can talk to it os.system('/bin/chmod 777 %s' %options.socket_file) with open(options.socket_file, "r") as pipecmd: while True: time.sleep(.001) try: line = pipecmd.readline() if line != '' : #New Data if line == '\n' : continue print ('Raw Text : %s' %line) encoded_string = line.encode("ascii", "ignore") line = encoded_string.decode() line = create_ascii(line) line = line.ascii print ('Line after ASCII : %s' %line) print ( 'Line Count : %s' %len(line) ) #line = data #go get my pid pid_process = '0' if options.pid == 'postfix' : #its a diverted postfix process get the actual pid from raw text pid_process = line.split('[',1)[1].split(']',1)[0] else : command = commands('/bin/ps -axww | /usr/bin/grep %s' %options.pid) print () #print (command.output) for n in range (0,len(command.output)) : if '/bin/ps -axww | /usr/bin/grep' not in command.output[n] and '/usr/bin/grep' not in command.output[n] and '/usr/local/bin/python3' not in command.output[n] : pid_process = ( command.output.split(' ')[0] ) #whats left should be my process ? break print ('PID Process : %s ' %pid_process ) if options.destination == 'local' : #Send to log here print ('Sending to Local S