#!/usr/bin/env python # # netinfolog2influxdb.py # # Copyright 2018 Todd Shadburn # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # import sys import socket #import logwatcher logfile = '/var/log/netinfo-events.log' #logfile = './netinfo-events.log' tsdb_server = 'localhost' tsdb_port = 4242 def cb_rotate(filepath): print 'File was rotated: %s' % (filepath) return def send_opentsdb_record(ts, dtype, attrs, stats): global tsdb_server global tsdb_port global tsdb_server_socket records = [] if dtype == 'syscpu': r = 'put %s %s %f fqdn=%s' % ('cpu.total.cpu.user',ts,float(stats[0]),attrs['hostname']) records.append(r) r = 'put %s %s %f fqdn=%s' % ('cpu.total.cpu.system',ts,float(stats[1]),attrs['hostname']) records.append(r) r = 'put %s %s %f fqdn=%s' % ('cpu.total.cpu.idle',ts,float(stats[2]),attrs['hostname']) records.append(r) r = 'put %s %s %f fqdn=%s' % ('cpu.total.cpu.iowait',ts,float(stats[3]),attrs['hostname']) records.append(r) r = 'put %s %s %f fqdn=%s' % ('cpu.total.cpu.nice',ts,float(stats[4]),attrs['hostname']) records.append(r) elif dtype == 'sysvm': r = 'put %s %s %d fqdn=%s' % ('memory.total.memory',ts,int(stats[0]),attrs['hostname']) records.append(r) r = 'put %s %s %d fqdn=%s' % ('memory.free.memory',ts,int(stats[1]),attrs['hostname']) records.append(r) r = 'put %s %s %d fqdn=%s' % ('memory.buffered.memory',ts,int(stats[2]),attrs['hostname']) records.append(r) r = 'put %s %s %d fqdn=%s' % ('memory.cached.memory',ts,int(stats[3]),attrs['hostname']) records.append(r) r = 'put %s %s %d fqdn=%s' % ('swap.total.swap',ts,int(stats[4]),attrs['hostname']) records.append(r) r = 'put %s %s %d fqdn=%s' % ('swap.free.swap',ts,int(stats[5]),attrs['hostname']) records.append(r) r = 'put %s %s %d fqdn=%s' % ('memory.active.memory',ts,int(stats[6]),attrs['hostname']) records.append(r) #r = 'put %s %s %d fqdn=%s' % ('memory.low.total',ts,int(stats[7]),attrs['hostname']) #records.append(r) #r = 'put %s %s %d fqdn=%s' % ('memory.low.free',ts,int(stats[8]),attrs['hostname']) #records.append(r) #r = 'put %s %s %d fqdn=%s' % ('memory.high.total',ts,int(stats[9]),attrs['hostname']) #records.append(r) #r = 'put %s %s %d fqdn=%s' % ('memory.high.free',ts,int(stats[10]),attrs['hostname']) #records.append(r) elif dtype == 'filesystem': if len(stats) != 5: print 'WARNING %s statistics are truncated' % (dtype) return o = attrs['object'].replace(':MOUNT','').replace('MOUNT','').replace(':\\','') #r = 'put %s %s %f fqdn=%s instance=%s' % ('df.%s.df_complex.usedpercent' %(o),ts,float(stats[0]),attrs['hostname'],o) r = 'put %s %s %f fqdn=%s instance=%s' % ('df.usedpercent',ts,float(stats[0]),attrs['hostname'],o) records.append(r) r = 'put %s %s %f fqdn=%s instance=%s' % ('df.used',ts,float(stats[3]),attrs['hostname'],o) records.append(r) r = 'put %s %s %f fqdn=%s instance=%s' % ('df.total',ts,float(stats[4]),attrs['hostname'],o) records.append(r) r = 'put %s %s %f fqdn=%s instance=%s' % ('df.free',ts,float(stats[4])-float(stats[3]),attrs['hostname'],o) records.append(r) elif dtype == 'interface': if len(stats) != 16: print 'WARNING %s statistics are truncated' % (dtype) return o = attrs['object'] #r = 'put %s %s %f fqdn=%s instance=%s' % ('interface.%s.if_octets.rx' %(o),ts,float(stats[0]),attrs['hostname'],o) r = 'put %s %s %f fqdn=%s instance=%s' % ('interface.if_octets.rx',ts,float(stats[0]),attrs['hostname'],o) records.append(r) r = 'put %s %s %f fqdn=%s instance=%s' % ('interface.if_packets.rx',ts,float(stats[1]),attrs['hostname'],o) records.append(r) r = 'put %s %s %f fqdn=%s instance=%s' % ('interface.if_errors.rx',ts,float(stats[2]),attrs['hostname'],o) records.append(r) r = 'put %s %s %f fqdn=%s instance=%s' % ('interface.if_dropped.rx',ts,float(stats[3]),attrs['hostname'],o) records.append(r) r = 'put %s %s %f fqdn=%s instance=%s' % ('interface.if_octets.tx',ts,float(stats[8]),attrs['hostname'],o) records.append(r) r = 'put %s %s %f fqdn=%s instance=%s' % ('interface.if_packets.tx',ts,float(stats[9]),attrs['hostname'],o) records.append(r) r = 'put %s %s %f fqdn=%s instance=%s' % ('interface.if_errors.tx',ts,float(stats[10]),attrs['hostname'],o) records.append(r) r = 'put %s %s %f fqdn=%s instance=%s' % ('interface.if_dropped.tx',ts,float(stats[11]),attrs['hostname'],o) records.append(r) elif dtype == 'diskstat': if len(stats) != 11: print 'WARNING %s statistics are truncated' % (dtype) return o = attrs['object'] r = 'put %s %s %f fqdn=%s instance=%s' % ('disk.octets.read',ts,float(stats[2])*512,attrs['hostname'],o) records.append(r) #r = 'put %s %s %f fqdn=%s instance=%s' % ('disk.%s.merged.read' % (attrs['object'].lower()),ts,float(stats[1]),attrs['hostname'],o) r = 'put %s %s %f fqdn=%s instance=%s' % ('disk.merged.read',ts,float(stats[1]),attrs['hostname'],o) records.append(r) r = 'put %s %s %f fqdn=%s instance=%s' % ('disk.sectors.read',ts,float(stats[2]),attrs['hostname'],o) records.append(r) r = 'put %s %s %f fqdn=%s instance=%s' % ('disk.waitms.read',ts,float(stats[3]),attrs['hostname'],o) records.append(r) r = 'put %s %s %f fqdn=%s instance=%s' % ('disk.octets.write',ts,float(stats[6])*512,attrs['hostname'],o) records.append(r) r = 'put %s %s %f fqdn=%s instance=%s' % ('disk.merged.write',ts,float(stats[5]),attrs['hostname'],o) records.append(r) r = 'put %s %s %f fqdn=%s instance=%s' % ('disk.sectors.write',ts,float(stats[6]),attrs['hostname'],o) records.append(r) r = 'put %s %s %f fqdn=%s instance=%s' % ('disk.waitms.write',ts,float(stats[7]),attrs['hostname'],o) records.append(r) r = 'put %s %s %f fqdn=%s instance=%s' % ('disk.pending_operations',ts,float(stats[8]),attrs['hostname'],o) records.append(r) r = 'put %s %s %f fqdn=%s instance=%s' % ('disk.disk_io_time.io_time',ts,float(stats[9]),attrs['hostname'],o) records.append(r) r = 'put %s %s %f fqdn=%s instance=%s' % ('disk.disk_io_time.weighted_io_time',ts,float(stats[10]),attrs['hostname'],o) records.append(r) elif dtype == 'gauge': try: r = 'put gauge.value %s %f fqdn=%s instance=%s' % (ts,float(stats[0]),attrs['hostname'],attrs['object'].replace('SITE-','')) records.append(r) except: print 'WARNING Invalid gauge data value \'%s\'' % (stats[0]) return elif dtype == 'counter': try: r = 'put counter.value %s %f fqdn=%s instance=%s' % (ts,float(stats[0]),attrs['hostname'],attrs['object']) records.append(r) except: print 'WARNING Invalid counter data value \'%s\'' % (stats[0]) return else: #print 'WARNING Unhandled dtype \'%s\'' % (dtype) return # Send the record for rec in records: #print rec try: tsdb_server_socket.send(rec+'\n') except: try: tsdb_connect(tsdb_server, tsdb_port) tsdb_server_socket.send(rec+'\n') except: pass return def cb_netinfo2tsdb(record): ts = None rdata = None try: ts,rdata = record.strip('\r\n').split(' ',1) except: # bad line format return if rdata[0:8] != 'hostname': # partial line, don't process return if not '|' in rdata: # not a performance data record return rattrs,rperf = rdata.split('|',1) attrs = {} for nvpair in rattrs.split(';',5): n,v = nvpair.split('=',1) attrs[n] = v if 'hostname' in attrs and not '.com' in attrs['hostname']: attrs['hostname'] = attrs['hostname'].lower() + '.internal.onedatascan.com' if attrs['eventflags'] == '0': try: dtype,rstats = rperf.split('=',1) stats = rstats.split(';') #print ts,dtype,stats send_opentsdb_record(ts, dtype, attrs, stats) except: # truncated line??? print 'WARNING Truncated perfdata \'%s\'' % (rperf) return return def tsdb_connect(host,port): global tsdb_server_socket try: if tsdb_server_socket: # Attempt to close the old socket tsdb_server_socket.close() tsdb_server_socket = socket.create_connection((host, port)) except: print 'WARNING Unable to connect to the TSDB server' tsdb_server_socket = None return if len(sys.argv) < 2: print 'Usage: netinfolog2influxdb.py logfile ...' sys.exit(2) # Connect to the TSDB endpoint tsdb_server_socket = None tsdb_connect(tsdb_server, tsdb_port) # Process the log file(s) for logfile in sys.argv[1:]: print 'Processing %s' % (logfile) fd = open(logfile, 'r') for ln in fd: cb_netinfo2tsdb(ln) fd.close() sys.exit(0)