class RiemannHandler(Handler): def __init__(self, config=None): # Initialize Handler Handler.__init__(self, config) if riemann_client is None: logging.error("Failed to load riemann_client module") return # Initialize options self.host = self.config['host'] self.port = int(self.config['port']) self.transport = self.config['transport'] # Initialize client if self.transport == 'tcp': self.transport = TCPTransport(self.host, self.port) else: self.transport = UDPTransport(self.host, self.port) self.client = Client(self.transport) self._connect() def get_default_config_help(self): """ Returns the help text for the configuration options for this handler """ config = super(RiemannHandler, self).get_default_config_help() config.update({ 'host': '', 'port': '', 'transport': 'tcp or udp', }) return config def get_default_config(self): """ Return the default config for the handler """ config = super(RiemannHandler, self).get_default_config() config.update({ 'host': '', 'port': 123, 'transport': 'tcp', }) return config def process(self, metric): """ Send a metric to Riemann. """ event = self._metric_to_riemann_event(metric) try: self.client.send_event(event) except Exception as e: self.log.error( "RiemannHandler: Error sending event to Riemann: %s", e) def _metric_to_riemann_event(self, metric): """ Convert a metric to a dictionary representing a Riemann event. """ # Riemann has a separate "host" field, so remove from the path. path = '%s.%s.%s' % ( metric.getPathPrefix(), metric.getCollectorPath(), metric.getMetricPath() ) return self.client.create_event({ 'host': metric.host, 'service': path, 'time': metric.timestamp, 'metric_f': float(metric.value), 'ttl': metric.ttl, }) def _connect(self): self.transport.connect() def _close(self): """ Disconnect from Riemann. """ if hasattr(self, 'transport'): self.transport.disconnect() def __del__(self): self._close()
class RiemannBroker(BaseModule): def __init__(self, modconf): BaseModule.__init__(self, modconf) self.host = getattr(modconf, 'host', 'localhost') self.port = int(getattr(modconf, 'port', '5555')) self.use_udp = getattr(modconf, 'use_udp', '0') == '1' self.buffer = [] self.ticks = 0 self.tick_limit = int(getattr(modconf, 'tick_limit', '300')) # Called by Broker so we can do init stuff # Conf from arbiter! def init(self): logger.info("[riemann broker] I init the %s server connection to %s:%d" % (self.get_name(), str(self.host), self.port)) if self.use_udp: transport = UDPTransport(self.host, self.port) else: transport = TCPTransport(self.host, self.port) transport.connect() self.client = Client(transport) # Returns a list of perfdata events def get_check_result_perfdata_events(self, perf_data, timestamp, host, service): events = [] metrics = PerfDatas(perf_data).metrics for e in metrics.values(): event_data = { 'host': host, 'service': service, 'time': timestamp, #'state': 'WARNING', 'metric_f': e.value, 'description': e.name, } attributes = {} if e.uom is not None: attributes['unit'] = unicode(e.uom) if e.warning is not None: attributes['warning'] = unicode(e.warning) if e.critical is not None: attributes['critical'] = unicode(e.critical) if e.min is not None: attributes['min'] = unicode(e.min) if e.max is not None: attributes['max'] = unicode(e.max) if attributes is not {}: event_data['attributes'] = attributes events.append( self.client.create_event(event_data) ) return events # Returns state_update points for a given check_result_brok data def get_state_update_points(self, data): events = [] if data['state'] != data['last_state'] or \ data['state_type'] != data['last_state_type']: events.append( self.client.create_event( { 'host': data['host_name'], 'service': data['service_description'], 'time': data['last_chk'], 'attributes': { 'state': data['state'], 'state_type': data['state_type'], 'output': data['output'] } } ) ) return events # A service check result brok has just arrived, we UPDATE data info with this def manage_service_check_result_brok(self, b): data = b.data events = [] events.extend( self.get_check_result_perfdata_events( data['perf_data'], data['last_chk'], data['host_name'], data['service_description'] ) ) events.extend( self.get_state_update_points(data) ) try: logger.debug("[riemann broker] Launching: %s" % str(events)) except UnicodeEncodeError: pass self.buffer.extend(events) # A host check result brok has just arrived, we UPDATE data info with this def manage_host_check_result_brok(self, b): data = b.data events = [] events.extend( self.get_check_result_perfdata_events( data['perf_data'], data['last_chk'], data['host_name'], None, ) ) events.extend( self.get_state_update_points(data) ) try: logger.debug("[riemann broker] Launching: %s" % str(events)) except UnicodeEncodeError: pass self.buffer.extend(events) def manage_unknown_host_check_result_brok(self, b): data = b.data events = [] events.extend( self.get_check_result_perfdata_events( data['perf_data'], data['last_chk'], data['host_name'], None, ) ) try: logger.debug("[riemann broker] Launching: %s" % str(events)) except UnicodeEncodeError: pass self.buffer.extend(events) def manage_unknown_service_check_result_brok(self, b): data = b.data events = [] events.extend( self.get_check_result_perfdata_events( data['perf_data'], data['time_stamp'], data['host_name'], data['service_description'] ) ) try: logger.debug("[riemann broker] Launching: %s" % str(events)) except UnicodeEncodeError: pass self.buffer.extend(events) # A log brok has arrived, we UPDATE data info with this def manage_log_brok(self, b): log = b.data['log'] log_event = LogEvent(log) if len(log_event) > 0: event_data = { 'host': b.data['hostname'], 'service': b.data['service_desc'], 'description': b.data['event_type'], 'time': b.data['time'] } attributes = {} # Add each property of the service in the point for prop in log_event: attributes[prop[0]] = unicode(prop[1]) self.buffer.append( self.client.create_event(event_data) ) def hook_tick(self, brok): if self.ticks >= self.tick_limit: logger.error("[riemann broker] Buffering ticks exceeded. Freeing buffer") self.buffer = [] self.ticks = 0 if len(self.buffer) > 0: try: for event in self.buffer: self.client.send_event(event) self.buffer.remove(event) self.ticks = 0 except: self.ticks += 1 logger.error("[riemann broker] Sending data Failed. Buffering state : %s / %s" % (self.ticks, self.tick_limit))