diff --git a/.gitignore b/.gitignore index a19c9ed..54a824f 100644 --- a/.gitignore +++ b/.gitignore @@ -129,4 +129,10 @@ dmypy.json .pyre/ # JUnit file -junit-test.xml \ No newline at end of file +junit-test.xml + +# VSCode +.vscode/ + +# Doc build +html_docs diff --git a/docs/index.asciidoc b/docs/index.asciidoc new file mode 100644 index 0000000..bf3cab5 --- /dev/null +++ b/docs/index.asciidoc @@ -0,0 +1,16 @@ +:ecs-repo-dir: {ecs-logging-root}/docs/ + +include::{docs-root}/shared/versions/stack/current.asciidoc[] +include::{docs-root}/shared/attributes.asciidoc[] + +ifdef::env-github[] +NOTE: For the best reading experience, +please view this documentation at https://www.elastic.co/guide/en/ecs-logging/python/current/index.html[elastic.co] +endif::[] + += ECS Logging Python Reference + +ifndef::env-github[] +include::./intro.asciidoc[Introduction] +include::./setup.asciidoc[Set up] +endif::[] diff --git a/docs/intro.asciidoc b/docs/intro.asciidoc new file mode 100644 index 0000000..31273fb --- /dev/null +++ b/docs/intro.asciidoc @@ -0,0 +1,10 @@ +[[intro]] +== Introduction + +ECS loggers are formatter/encoder plugins for your favorite logging libraries. +They make it easy to format your logs into ECS-compatible JSON. + +TIP: Want to learn more about ECS, ECS logging, and other available language plugins? +See the {ecs-logging-ref}/intro.html[ECS logging guide]. + +Ready to jump into `ecs-logging-python`? <>. diff --git a/docs/setup.asciidoc b/docs/setup.asciidoc new file mode 100644 index 0000000..c57db0e --- /dev/null +++ b/docs/setup.asciidoc @@ -0,0 +1,199 @@ +[[installation]] +== Installation + +[source,cmd] +---- +$ python -m pip install ecs-logging +---- + +[float] +[[gettingstarted]] +== Getting Started + +`ecs-logging-python` has formatters for the standard library +https://docs.python.org/3/library/logging.html[`logging`] module +and the https://www.structlog.org/en/stable/[`structlog`] package. + +[float] +[[logging]] +=== Standard Library `logging` Module + +[source,python] +---- +import logging +import ecs_logging + +# Get the Logger +logger = logging.getLogger("app") +logger.setLevel(logging.DEBUG) + +# Add an ECS formatter to the Handler +handler = logging.StreamHandler() +handler.setFormatter(ecs_logging.StdlibFormatter()) +logger.addHandler(handler) + +# Emit a log! +logger.debug("Example message!", extra={"http.request.method": "get"}) +---- + +[source,json] +---- +{ + "@timestamp": "2020-03-20T18:11:37.895Z", + "ecs": { + "version": "1.6.0" + }, + "http": { + "request": { + "method": "get" + } + }, + "log": { + "level": "debug", + "logger": "app", + "origin": { + "file": { + "line": 14, + "name": "test.py" + }, + "function": "func" + }, + "original": "Example message!" + }, + "message": "Example message!" +} +---- + +[float] +==== Excluding Fields + +You can exclude fields from being collected by using the `exclude_fields` option +in the `StdlibFormatter` constructor: + +[source,python] +---- +from ecs_logging import StdlibFormatter + +formatter = StdlibFormatter( + exclude_fields=[ + # You can specify individual fields to ignore: + "log.original", + # or you can also use prefixes to ignore + # whole categories of fields: + "process", + "log.origin", + ] +) +---- + +[float] +==== Limiting Stack Traces + +The `StdlibLogger` automatically gathers `exc_info` into ECS `error.*` fields. +If you'd like to control the number of stack frames that are included +in `error.stack_trace` you can use the `stack_trace_limit` parameter +(by default all frames are collected): + +[source,python] +---- +from ecs_logging import StdlibFormatter + +formatter = StdlibFormatter( + # Only collects 3 stack frames + stack_trace_limit=3, +) +formatter = StdlibFormatter( + # Disable stack trace collection + stack_trace_limit=0, +) +---- + +[float] +[[structlog]] +=== Structlog Example + +[source,python] +---- +import structlog +import ecs_logging + +# Configure Structlog +structlog.configure( + processors=[ecs_logging.StructlogFormatter()], + wrapper_class=structlog.BoundLogger, + context_class=dict, + logger_factory=structlog.PrintLoggerFactory(), +) + +# Get the Logger +logger = structlog.get_logger("app") + +# Add additional context +logger = logger.bind(**{ + "http": { + "version": "2", + "request": { + "method": "get", + "bytes": 1337, + }, + }, + "url": { + "domain": "example.com", + "path": "/", + "port": 443, + "scheme": "https", + "registered_domain": "example.com", + "top_level_domain": "com", + "original": "https://example.com", + } +}) + +# Emit a log! +logger.debug("Example message!") +---- + +[source,json] +---- +{ + "@timestamp": "2020-03-26T13:08:11.728Z", + "ecs": { + "version": "1.6.0" + }, + "http": { + "request": { + "bytes": 1337, + "method": "get" + }, + "version": "2" + }, + "log": { + "level": "debug" + }, + "message": "Example message!", + "url": { + "domain": "example.com", + "original": "https://example.com", + "path": "/", + "port": 443, + "registered_domain": "example.com", + "scheme": "https", + "top_level_domain": "com" + } +} +---- + +[float] +[[correlation]] +== Elastic APM Log Correlation + +`ecs-logging-python` supports automatically collecting https://www.elastic.co/guide/en/ecs/master/ecs-tracing.html[ECS tracing fields] +from the https://github.com/elastic/apm-agent-python[Elastic APM Python agent] in order to +https://www.elastic.co/guide/en/apm/agent/python/current/log-correlation.html[correlate logs to spans, transactions and traces] in Elastic APM. + +[float] +[[filebeat]] +== Install Filebeat + +The best way to collect the logs once they are ECS-formatted is with https://www.elastic.co/beats/filebeat[Filebeat]: + +include::{ecs-repo-dir}/setup.asciidoc[tag=configure-filebeat]