#!/usr/bin/env python ########################################################################## # elasticlog.py - Enable/disable logging to an elasticsearch environment ########################################################################## # Copyright 2017 Todd Shadburn ########################################################################## # Python environment requirements: # - Python 2.7+ or 3.x+ # - Install CMRESHandler module # pip install CMRESHandler # # Environment variables required: # ELASTICLOG_ENABLE - 1=enable, 0=disable(default) # ELASTICLOG_HOST - hostname(s) for the elastic cluster # ELASTICLOG_USERNAME - elastic login username # ELASTICLOG_PASSWORD - elastic login password # ELASTICLOG_INDEXNAME - elastic index name to use ########################################################################## import os import logging def setup_elasticsearch_logging(logger=None, appname=None, owner=None, deploymentstage=None, *args, **kwargs): """ Enable elaseticsearch logging if we have all our config items appname/owner/deploymentstage are required arguments (for ES logging fields) Additional user-specified ES logging fields can be passed in kwargs (name=value) """ if not appname or not owner or not deploymentstage: # Missing a required argument, don't continue raise ValueError('elasticlog: Missing a required argument, not enabling.') return None # setup basic logging (to the console anyway) if not already configured log = None if logger: # Use the logging already setup by the application log = logger else: # Create a basic console logger for the application log = logging.getLogger(appname) log.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') console_handler = logging.StreamHandler() console_handler.setLevel(logging.INFO) console_handler.setFormatter(formatter) log.addHandler(console_handler) # Pull in cmreshandler which supports ElasticSearch try: from cmreslogging.handlers import CMRESHandler except: # No cmredhandler, just return the console logger return log # Process environment variables for elasticlog # This makes use of this module; 1)easy and 2)consistent ELASTICLOG_ENABLE=0 if 'ELASTICLOG_ENABLE' in os.environ: ELASTICLOG_ENABLE=int(os.environ['ELASTICLOG_ENABLE']) if ELASTICLOG_ENABLE == 0: # don't enable elasticsearch logging but return # the console logger return log ELASTICLOG_HOST='' if 'ELASTICLOG_HOST' in os.environ: ELASTICLOG_HOST = os.environ['ELASTICLOG_HOST'] ELASTICLOG_USERNAME='' if 'ELASTICLOG_USERNAME' in os.environ: ELASTICLOG_USERNAME = os.environ['ELASTICLOG_USERNAME'] ELASTICLOG_PASSWORD='' if 'ELASTICLOG_PASSWORD' in os.environ: ELASTICLOG_PASSWORD = os.environ['ELASTICLOG_PASSWORD'] ELASTICLOG_INDEXNAME='' if 'ELASTICLOG_INDEXNAME' in os.environ: ELASTICLOG_INDEXNAME = os.environ['ELASTICLOG_INDEXNAME'] if (ELASTICLOG_HOST == '' or ELASTICLOG_USERNAME == '' or ELASTICLOG_PASSWORD == '' or ELASTICLOG_INDEXNAME == ''): # Missing a parameter, don't continue raise ValueError('elasticlog: Missing a required environment variable, not enabling.') # Return the console logger return log # We've got all the info we need to add the elasticsearch log handler # Build additional fields for ES, starting with required fields es_addl_fields = { 'AppName': appname, 'Owner': owner, 'DeploymentStage': deploymentstage, } # Then add any user-specified fields for n,v in kwargs: es_addl_fields[n] = k # Now, connect to ElasticSearch and add the handler ehandler = CMRESHandler(hosts=[{'host': ELASTICLOG_HOST, 'port': 9200}], auth_type=CMRESHandler.AuthType.BASIC_AUTH, auth_details=(ELASTICLOG_USERNAME,ELASTICLOG_PASSWORD), use_ssl=True, verify_ssl=False, es_index_name=ELASTICLOG_INDEXNAME, es_additional_fields=es_addl_fields, ) ehandler.setLevel(logging.INFO) log.addHandler(elastic_handler) return log