LogicMachine Forum
Automatic export all logs and send by mail - Printable Version

+- LogicMachine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8)
+--- Thread: Automatic export all logs and send by mail (/showthread.php?tid=1918)

Pages: 1 2


RE: Automatic export all logs and send by mail - manos@dynamitec - 04.10.2023

Hello Admin,

I can understand that but we have a LM5Lp2 and using it on various sites as a logger when required. It is not that it is running for very long periods. I just want to overcome the 50k data points limit. In the projects we have (not logging everything of course), I would guess that 50K telegrams will be enough for one day. If the LM is logging for 7-15 days then this file will be 15 time written or so. When installed on a new site for example we can delete all files from the FTP server and start over with the logging.

Is this possible to do?

Regards,


RE: Automatic export all logs and send by mail - admin - 05.10.2023

See this example: https://openrb.com/example-export-last-hour-csv-object-log-file-to-external-ftp-server-from-lm2/
It has both local file and remote FTP options.


RE: Automatic export all logs and send by mail - manos@dynamitec - 16.01.2024

(05.10.2023, 06:52)admin Wrote: See this example: https://openrb.com/example-export-last-hour-csv-object-log-file-to-external-ftp-server-from-lm2/
It has both local file and remote FTP options.

Hello Admin,

I have applied the solution from the example on the link, although unfortunately I just noticed that not all fields are included on the csv file. I would like to export all data that can be seen on the object logs utility. For the moment only timestamp, address, name and value is included in the csv export...

I am using the following script:
Code:
   --ftp file    ftpfile = string.format('/home/ftp/%s.csv', os.date('%Y-%m-%d_%H-%M'))    -- get past 12 hours data (43200 seconds)    logtime = os.time() - 12 * 60 * 60          -- list of objects by id     objects = {}          -- objects with logging enabled     query = 'SELECT address, datatype, name FROM objects WHERE disablelog=0'     for _, object in ipairs(db:getall(query)) do       objects[ tonumber(object.address) ] = {         datatype = tonumber(object.datatype),         name = tostring(object.name or ''),       }     end          -- csv buffer     buffer = { '"date","address","name","value"' }          -- get object logs     query = 'SELECT src, address, datahex, logtime, eventtype FROM objectlog WHERE logtime >= ? ORDER BY id DESC'     for _, row in ipairs(db:getall(query, logtime)) do       object = objects[ tonumber(row.address) ]            -- found matching object and event type is group write       if object and row.eventtype == 'write' then         datatype = object.datatype              -- check that object datatype is set         if datatype then           -- decode data           data = knxdatatype.decode(row.datahex, datatype)                -- remove null chars from char/string datatype           if datatype == dt.char or datatype == dt.string then             data = data:gsub('%z+', '')           -- date to DD.MM.YYYY           elseif datatype == dt.date then             data = string.format('%.2d.%.2d.%.2d', data.day, data.month, data.year)           -- time to HH:MM:SS           elseif datatype == dt.time then             data = string.format('%.2d:%.2d:%.2d', data.hour, data.minute, data.second)           end         else           data = ''         end              -- format csv row         logdate = os.date('%Y.%m.%d %H:%M:%S', row.logtime)         csv = string.format('%q,%q,%q,%q', logdate, knxlib.decodega(row.address), object.name, tostring(data))              -- add to buffer         table.insert(buffer, csv)       end     end              -- upload to ftp only when there's data in buffer     if #buffer > 1 then       data = table.concat(buffer, '\r\n')       io.writefile(ftpfile, data)     end

How can this be modified to include the type (read/write) and source address fields?

Kind Regards,


RE: Automatic export all logs and send by mail - admin - 17.01.2024

See this updated example: https://kb.logicmachine.net/scripting/export-last-hour-csv/


RE: Automatic export all logs and send by mail - domotiqa - 20.02.2024

(17.01.2022, 08:17)admin Wrote: Escaping of the "to" address was missing.
Here's a rewritten script with clearer structure. You only need to modify the to/settings/subject at the to top of the script. SSL settings do not matter anymore because newer SSL library automatically negotiates the highest supported SSL/TLS version between server/client.
Code:
to = 'to@example.com' settings = {   -- "from" field, only e-mail must be specified here   from = 'sender@example.com',   -- smtp username   user = 'sender@example.com',   -- smtp password   password = '12345678',   -- smtp server   server = 'smtp.gmail.com',   -- smtp server port   port = 465,   -- enable ssl, required for gmail smtp   secure = 'sslv23', } subject = 'CSV logs' logtime = os.time() - 60 * 60 -- last hour (3600 seconds) buffer = {'"date","address","name","value"'} query = [[   SELECT o.id, o.datatype, o.name, ol.datahex, ol.logtime, ol.eventtype   FROM objectlog ol   JOIN objects o ON ol.address=o.id   WHERE ol.logtime >= ?   ORDER BY ol.id DESC ]] for _, row in ipairs(db:getall(query, logtime)) do   if row.datatype and row.eventtype == 'write' then     data = grp.decodevalue(row.datahex, row.datatype)     logdate = os.date('%Y.%m.%d %H:%M:%S', row.logtime)     buffer[ #buffer + 1 ] = string.format('%q,%q,%q,%q',       logdate, knxlib.decodega(row.id), row.name, tostring(data))   end end csv = table.concat(buffer, '\r\n') smtp = require('socket.smtp') mime = require('mime') ltn12 = require('ltn12') function escape(v)   return '<' .. tostring(v) .. '>' end to = escape(to) msgt = {   headers = {     to = to,     ['content-type'] = 'text/csv',     ['content-disposition'] = 'attachment; filename="logs.csv"',     ['content-transfer-encoding'] = 'BASE64',     subject = subject,   },   body = ltn12.source.chain(     ltn12.source.string(csv),     ltn12.filter.chain(mime.encode('base64'), mime.wrap('base64'))   ) } settings.source = smtp.message(msgt) settings.from = escape(settings.from) settings.rcpt = { to } res, err = smtp.send(settings) log(res, err)

Hi, thanks for the script,

is there an easy way to separate in different csv file the log object and send them in one email?


RE: Automatic export all logs and send by mail - domotiqa - 20.02.2024

I test it but I think the smtp output of my customer is blocked (result 1, nil) for the log. I will try on my test server


Code:
smtp = require('socket.smtp') mime = require('mime') ltn12 = require('ltn12') to = 'xxx@gmail.com' subject = 'CSV logs' message='export log' logtime = os.time() - 60 * 60--*24*7 -- last hour (3600 seconds) -------------- cherche les cpt query = [[   SELECT ol2.name   FROM objects ol2   WHERE ol2.disablelog = 0 ]] csv={} nombre=0 nom={} for _, objectlog in ipairs(db:getall(query, logtime)) do     nombre=nombre+1       nom[nombre]=objectlog.name   ----------------   --buffer = {'"date","address","name","value"'}   buffer = {'"date","name","value"'}   query2 = [[     SELECT o.id, o.datatype, o.name, ol.datahex, ol.logtime, ol.eventtype     FROM objectlog ol     JOIN objects o ON ol.address=o.id     WHERE (ol.logtime >= ?)     ORDER BY ol.id DESC   ]]   for _, row in ipairs(db:getall(query2, logtime)) do     if row.datatype and row.eventtype == 'write' and row.name == nom[nombre] then       data = grp.decodevalue(row.datahex, row.datatype)       logdate = os.date('%Y.%m.%d %H:%M:%S', row.logtime)       buffer[ #buffer + 1 ] = string.format('%q,%q,%q',         --logdate, knxlib.decodega(row.id), row.name, tostring(data))         logdate, string.split(row.name,'-')[5], tostring(data))     end   end   csv[nombre] = table.concat(buffer, '\r\n')      end --pour chaque object ayant log attachement = {} nombre=0 for _, nomCpt in ipairs(nom) do   nombre=nombre+1   -- create file   table.insert(attachement, {filename=nomCpt .. '.csv', filedata=csv[nombre], mimetype='text/csv'}) end mailattach(to, subject, message, attachement)

and function in common
Code:
--******************************** -- send an e-mail with attachments function mailattach(to, subject, message, files)   local settings = {     -- "from" field, only e-mail must be specified here     from = 'notification@xxx.com',     -- smtp username     user = 'notification@xxx.com',     -- smtp password     password = 'xxx',     -- smtp server     server = 'xxx.net',     --server = 'xxxx.net',         -- smtp server port     port = 465,     --port = 587,     -- enable ssl, required for gmail smtp     secure = 'sslv23',     --secure = 'tlsv1_2',   } -- ssl0.ovh.net sur port 465 -- ns0.ovh.net sur ports 25, 5025, 587, enfin tout ce que j'essaye...   local smtp = require('socket.smtp')   if type(to) ~= 'table' then     to = { to }   end   for index, email in ipairs(to) do     to[ index ] = '<' .. tostring(email) .. '>'   end     -- escape double quotes in file name   for _, object in ipairs(table) do     --files[_].filename = files[_].filename:gsub('"', '\\"')     end      -- fixup from field     local from = '<' .. tostring(settings.from) .. '>'     -- message headers and body   email = {headers = {}, body = {}}   email.headers = {         to = table.concat(to, ', '),         subject = subject,         ['From'] = from,         --['Content-type'] = 'text/html; charset=utf-8',       }   email.body[1] = { headers = { ['Content-Type'] = 'text/html; charset=utf-8', }, body = mime.eol(0, message) }   -- adding attachements   for _, object in ipairs(files) do   email.body[_+1] = {       headers = { ['Content-Type'] = files[_].mimetype or 'text/plain', ['Content-Disposition'] = 'attachment; filename="' .. files[_].filename ..'"', ['Content-Transfer-Encoding'] = 'BASE64', },       body = ltn12.source.chain( ltn12.source.string(files[_].filedata), ltn12.filter.chain(mime.encode('base64'), mime.wrap() ) )     }   end     settings.source = smtp.message(email)   settings.from = from   settings.rcpt = to   return smtp.send(settings) end