| # Python Agent Log Reporter |
| |
| This functionality reports logs collected from the Python logging module (in theory, also logging libraries depending on the core logging module) and loguru module. |
| |
| From Python agent 1.0.0, the log reporter is automatically enabled and can be disabled through `agent_log_reporter_active=False` or `SW_AGENT_LOG_REPORTER_ACTIVE=False`. |
| |
| Log reporter supports all three protocols including `grpc`, `http` and `kafka`, which shares the same config `agent_protocol` with trace reporter. |
| |
| If chosen `http` protocol, the logs will be batch-reported to the collector REST endpoint `oap/v3/logs`. |
| |
| If chosen `kafka` protocol, please make sure to config |
| [kafka-fetcher](https://skywalking.apache.org/docs/main/v10.0.1/en/setup/backend/kafka-fetcher/) |
| on the OAP side, and make sure Python agent config `kafka_bootstrap_servers` points to your Kafka brokers. |
| |
| **Please make sure OAP is consuming the same Kafka topic as your agent produces to, `kafka_namespace` must match OAP side configuration `plugin.kafka.namespace`** |
| |
| `agent_log_reporter_active=True` - Enables the log reporter. |
| |
| `agent_log_reporter_max_buffer_size` - The maximum queue backlog size for sending log data to backend, logs beyond this are silently dropped. |
| |
| Alternatively, you can pass configurations through environment variables. |
| Please refer to the [Configuration Vocabulary](../Configuration.md) for the list of environment variables associated with the log reporter. |
| |
| ## Specify a logging level |
| > [Important] Agent will only report logs that passes the default level threshold logging.getLogger().setLevel(logging.WARNING) |
| > For example, if your logger level is logging.INFO, agent will not report info logs even if you set `agent_log_reporter_level` to `INFO` |
| |
| Additional to the code level configuration, only the logs with a level equal to or higher than the |
| specified configuration will be collected and reported. |
| |
| In other words, the agent skips reporting some unwanted logs based on your level threshold even though they are still logged. |
| |
| `log_reporter_level` - The string name of a logger level. |
| |
| Note that it also works with your custom logger levels, simply specify its string name in the config. |
| |
| ### Ignore log filters |
| The following config is disabled by default. When enabled, the log reporter will collect logs disregarding your custom log filters. |
| |
| For example, if you attach the filter below to the logger - the default behavior of log reporting aligns with the filter |
| (not reporting any logs with a message starting with `SW test`) |
| ```python |
| class AppFilter(logging.Filter): |
| def filter(self, record): |
| return not record.getMessage().startswith('SW test') |
| |
| logger.addFilter(AppFilter()) |
| ``` |
| However, if you do would like to report those filtered logs, set the `log_reporter_ignore_filter` to `True`. |
| |
| |
| ## Formatting |
| Note that regardless of the formatting, Python agent will always report the following three tags - |
| |
| `level` - the logger level name |
| |
| `logger` - the logger name |
| |
| `thread` - the thread name |
| |
| ### Limit stacktrace depth |
| You can set the `cause_exception_depth` config entry to a desired level(defaults to 10), which limits the output depth of exception stacktrace in reporting. |
| |
| This config limits agent to report up to `limit` stacktrace, please refer to [Python traceback](https://docs.python.org/3/library/traceback.html#traceback.print_tb) for more explanations. |
| |
| ### Customize the reported log format |
| You can choose to report collected logs in a custom layout. |
| |
| If not set, the agent uses the layout below by default, else the agent uses your custom layout set in `log_reporter_layout`. |
| |
| `'%(asctime)s [%(threadName)s] %(levelname)s %(name)s - %(message)s'` |
| |
| If the layout is set to `None`, the reported log content will only contain |
| the pre-formatted `LogRecord.message`(`msg % args`) without any additional styles or extra fields, stacktrace will be attached if an exception was raised. |
| |
| ### Transmit un-formatted logs |
| You can also choose to report the log messages without any formatting. |
| It separates the raw log msg `logRecord.msg` and `logRecord.args`, then puts them into message content and tags starting from `argument.0`, respectively, along with an `exception` tag if an exception was raised. |
| |
| Note when you set `log_reporter_formatted` to False, it ignores your custom layout introduced above. |
| |
| As an example, the following code: |
| ```python |
| logger.info("SW test log %s %s %s", 'arg0', 'arg1', 'arg2') |
| ``` |
| |
| Will result in: |
| ```json |
| { |
| "content": "SW test log %s %s %s", |
| "tags": [ |
| { |
| "key": "argument.0", |
| "value": "arg0" |
| }, |
| { |
| "key": "argument.1", |
| "value": "arg1" |
| }, |
| { |
| "key": "argument.2", |
| "value": "arg2" |
| } |
| ] |
| } |
| ``` |
| |
| ## Print trace ID in your logs |
| To print out the trace IDs in the logs, simply add `%(tid)s` to the `agent_log_reporter_layout`. |
| |
| You can take advantage of this feature to print out the trace IDs on any channel you desire, not limited to reporting logs to OAP, |
| this can be achieved by using any formatter you prefer in your own application logic. |