class QueryRunner(object): """ Query Runner. a class to handle query to splunkd. It grabs a splunkd object according to the splunkrc params provided: - If splunkrc is a dictionary, it will create a new splunkd object. - If given other object type, it will do do Dependency Injection on _splunkd """ def __init__(self, splunkrc, index_name=INSTRUMENTATION_INDEX_NAME, owner='-', app=INST_APP_NAME, result_reader=QueryRunnerResult): self.splunkrc = splunkrc or SPLUNKRC self.result_reader = result_reader if type(self.splunkrc) is dict: self._splunkd = Splunkd(**self.splunkrc) else: self._splunkd = splunkrc self._splunkd.namespace['owner'] = owner self._splunkd.namespace['app'] = app if self._splunkd.has_index(index_name): self._index = self._splunkd.get_index(index_name) else: logging.error('ERROR: INDEX IS NOT AVAILABLE') raise (Exception("ERROR INDEX UNAVAILABLE")) def search(self, search_cmd, **kwargs): """Submit a new search. It is a wrapper to the private method _query. """ return self._query(search_cmd, **kwargs) def _query(self, search_cmd, **kwargs): """Query. Note that earliest is inclusive & latest is exclusive: [earliest, latest) (Prevents getting last-second events again during the next query) """ job = self._splunkd.search(search_cmd, **kwargs) while not job.is_done(): time.sleep(0.2) result = self.result_reader(job.results(count=0)) if hasattr(result, 'job'): result.job = job return result
class EventWriter(object): """ Event Writer class This class handles writing to the index. It grabs a splunkd object according to the splunkrc params provided: - If splunkrc is a dictionary, it will create a new splunkd object. - If given other object type, it will do do Dependency Injection on _splunkd """ def __init__(self, splunkrc=None, index_name=None): self.splunkrc = splunkrc or SPLUNKRC self.socket = None self._index = None if type(self.splunkrc) is dict: self._splunkd = Splunkd(**self.splunkrc) else: self._splunkd = splunkrc if index_name: if self._splunkd.has_index(index_name): self._index = self._splunkd.get_index(index_name) else: logging.error('ERROR: INDEX IS NOT AVAILABLE') raise Exception("ERROR INDEX UNAVAILABLE") def submit(self, event, host=None, source=None, sourcetype=INSTRUMENTATION_SOURCETYPE): # Note: We used to use the ordinary index.submit method from splunklib, # instead of using a socket. However, that method uses receivers/simple, # an endpoint that bypasses index time field extraction (which we rely on). temp_socket = self._index.attach(host=host, source=source, sourcetype=sourcetype) temp_socket.send(self.marshal_event(event)) temp_socket.close() def open_socket(self, host=None, source=None, sourcetype=INSTRUMENTATION_SOURCETYPE): ''' Opens a socket to stream events to be indexed, saving it as an instance variable for later use when submit_via_socket is called. :param host: :param source: :param sourcetype: :return: ''' self.socket = self._index.attach(host=host, source=source, sourcetype=sourcetype) return self.socket def close_socket(self): ''' Closes socket and set it to none ''' if self.socket: self.socket.close() self.socket = None def submit_via_socket(self, event): """ Submit the event provided using socket connection. """ event = self.marshal_event(event) if not self.socket: self.open_socket() self.socket.send(event) @staticmethod def marshal_event(event): ''' Marshals the given event into a json string, suitable for passing to an open receivers/stream socket. ''' if not isinstance(event, (str, bytes)): event = json.dumps(event, default=json_serial) if isinstance(event, str) and sys.version_info >= (3, 0): event = event.encode() return event
class EventWriter(object): """ Event Writer class This class handles writing to the index. It grabs a splunkd object according to the splunkrc params provided: - If splunkrc is a dictionary, it will create a new splunkd object. - If given other object type, it will do do Dependency Injection on _splunkd """ def __init__(self, splunkrc=None, index_name=None): self.splunkrc = splunkrc or SPLUNKRC self.socket = None self._index = None if type(self.splunkrc) is dict: self._splunkd = Splunkd(**self.splunkrc) else: self._splunkd = splunkrc if index_name: if self._splunkd.has_index(index_name): self._index = self._splunkd.get_index(index_name) else: logging.error('ERROR: INDEX IS NOT AVAILABLE') raise (Exception("ERROR INDEX UNAVAILABLE")) def submit(self, event, host=None, source=None, sourcetype=None): """Submit a new event directly to the index.""" if self._index: self._index.submit(event, host=host, source=source, sourcetype=sourcetype) else: logging.error('ERROR: INDEX IS NOT AVAILABLE') raise Exception("ERROR INDEX UNAVAILABLE") def open_socket(self, host=None, source=None, sourcetype=None): ''' Opens a socket to stream events to be indexed :param host: :param source: :return: ''' self.socket = self._index.attach(host=host, source=source, sourcetype=INSTRUMENTATION_SOURCETYPE) return self.socket def close_socket(self): ''' Closes socket and set it to none ''' if self.socket: self.socket.close() self.socket = None def submit_via_socket(self, event): """ Submit the event provided using socket connection. """ if not isinstance(event, str): event = json.dumps(event, default=json_serial) if not self.socket: self.open_socket() self.socket.send(event)