Is there a way to have one complete output log with custom_dimensions
? I see in the monitor tab (of Azure Functions) that only messages with operation_Id
and customDimensions['InvocationId']
are shown. Is there a way to add these two parameters all the log-messages from opencensus?
I know you can use a second logger. But that only helps for debugging. For running the Azure Functions in production, I need to look at both streams. That is possible, but inefficient and frustrating, as the information is disconnected and impossible to summarize.
However another alternative would be joining the streams on the Azure Monitor side. But I can't do that unless I know the current InvocationId
or operation_Id
. Therefore my question if I can add any of those two IDs to my current log-message
My minimal example __init__.py
looks like this:
from opencensus.ext.azure.log_exporter import AzureLogHandler
import logging.config
import yaml
import azure.functions as func
# Load logging configuration
with open("logging.yaml", 'rt') as f: # for local debugging add the console handler to the output
config_data = yaml.safe_load(f.read())
logging.config.dictConfig(config_data)
def main(mytimer: func.TimerRequest) -> None:
try:
someID = 14
logging.debug('debug message',extra = {'custom_dimensions': {'ID': someID}})
logging.info('info message',extra = {'custom_dimensions': {'ID': someID}})
logging.warning('warn message',extra = {'custom_dimensions': {'ID': someID}})
logging.error('error message',extra = {'custom_dimensions': {'ID': someID}})
logging.critical('critical message',extra = {'custom_dimensions': {'ID': someID}})
except Exception as e:
logging.error("Main program failed with error: " + str(e))
I prefer to keep my logging configuration in a logging.yaml
:
version: 1
formatters:
simple:
format: '%(asctime)s | %(levelname)-8s | %(module)s:%(funcName)s:%(lineno)d | %(message)s'
handlers:
azure:
class: opencensus.ext.azure.log_exporter.AzureLogHandler
level: DEBUG
formatter: simple
instrumentation_key: 'your-key'
loggers:
simpleExample:
level: DEBUG
handlers: [azure]
propagate: no
root:
level: INFO
handlers: [azure]
After finding the right part in the documentation it was surprisingly easy:
def main(mytimer: func.TimerRequest, context: func.Context) -> None:
try:
invocation_id = context.invocation_id
# Function continues here.
except Exception as e:
logging.error("Main program failed with error: " + str(e))
Be aware that this solution only works if func.Context
is assigned to context
. Using any other name than context
results in errors for me -.-