{"id":16911909,"url":"https://github.com/vitalijr2/aws-lambda-slf4j","last_synced_at":"2025-06-11T11:15:19.751Z","repository":{"id":223191759,"uuid":"759530379","full_name":"vitalijr2/aws-lambda-slf4j","owner":"vitalijr2","description":"An SLF4J Logger implementation for AWS Lambda and CloudWatch.","archived":false,"fork":false,"pushed_at":"2025-06-02T06:36:06.000Z","size":412,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-05T07:05:49.586Z","etag":null,"topics":["aws-lambda","cloudwatch-logs","json-logging","slf4j","slf4j-api","slf4j-logger","slf4j-loggers","slf4j-provider"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vitalijr2.png","metadata":{"files":{"readme":"readme.md","changelog":"changelog.md","contributing":"contributing.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"security.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"custom":["https://buymeacoffee.com/vitalij_r2","https://send.monobank.ua/jar/9r5bd6ejUC?f=enabled\u0026t=aws-lambda-slf4j","https://next.privat24.ua/send/cblin"],"ko_fi":"vitalij_r2","liberapay":"vitalij_r2"}},"created_at":"2024-02-18T20:48:42.000Z","updated_at":"2025-05-25T06:40:22.000Z","dependencies_parsed_at":"2024-03-19T13:30:21.035Z","dependency_job_id":"92037a18-a00f-4a4a-8012-abbc846153d1","html_url":"https://github.com/vitalijr2/aws-lambda-slf4j","commit_stats":{"total_commits":20,"total_committers":1,"mean_commits":20.0,"dds":0.0,"last_synced_commit":"2ff6a77a5c0423fe840a9fccac1022aa5d28d3a4"},"previous_names":["vitalijr2/aws-lambda-slf4j"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitalijr2%2Faws-lambda-slf4j","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitalijr2%2Faws-lambda-slf4j/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitalijr2%2Faws-lambda-slf4j/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitalijr2%2Faws-lambda-slf4j/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vitalijr2","download_url":"https://codeload.github.com/vitalijr2/aws-lambda-slf4j/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vitalijr2%2Faws-lambda-slf4j/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259253604,"owners_count":22829145,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws-lambda","cloudwatch-logs","json-logging","slf4j","slf4j-api","slf4j-logger","slf4j-loggers","slf4j-provider"],"created_at":"2024-10-13T19:08:01.851Z","updated_at":"2025-06-11T11:15:19.689Z","avatar_url":"https://github.com/vitalijr2.png","language":"Java","funding_links":["https://buymeacoffee.com/vitalij_r2","https://send.monobank.ua/jar/9r5bd6ejUC?f=enabled\u0026t=aws-lambda-slf4j","https://next.privat24.ua/send/cblin","https://ko-fi.com/vitalij_r2","https://liberapay.com/vitalij_r2"],"categories":[],"sub_categories":[],"readme":"# SLF4J for AWS Lambda\n\nAn [SLF4J][] Logger implementation for [AWS Lambda][lambda]\nand [CloudWatch][cloudwatch].\n\n[![Java Version][java-version]][jdk-download]\n[![License][license-badge]][license-link]\n[![GitHub master check runs][github-master-check-runs]][github-master-check-runs-link]\n[![Codacy Badge][codacy-badge]][codacy-badge-link]\n[![Codacy Coverage][codacy-coverage]][codacy-coverage-link]\n![GitHub commit activity][github-commit-activity]\n[![Today's hits][today-hits]][today-hits-link]\n\n| Logger                           | Release                                                                                                                                                                                                               | Javadoc                                                                                                                                                                                             |\n|----------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| **aws-lambda-slf4j-logger**      | [![Maven Central](https://img.shields.io/maven-central/v/io.github.vitalijr2.logging/aws-lambda-slf4j-logger)](https://search.maven.org/artifact/io.github.vitalijr2.logging/aws-lambda-slf4j-logger)           | [![Javadoc](https://javadoc.io/badge2/io.github.vitalijr2.logging/aws-lambda-slf4j-logger/javadoc.svg)](https://javadoc.io/doc/io.github.vitalijr2.logging/aws-lambda-slf4j-logger)           |\n| **aws-lambda-slf4j-json-logger** | [![Maven Central](https://img.shields.io/maven-central/v/io.github.vitalijr2.logging/aws-lambda-slf4j-json-logger)](https://search.maven.org/artifact/io.github.vitalijr2.logging/aws-lambda-slf4j-json-logger) | [![Javadoc](https://javadoc.io/badge2/io.github.vitalijr2.logging/aws-lambda-slf4j-json-logger/javadoc.svg)](https://javadoc.io/doc/io.github.vitalijr2.logging/aws-lambda-slf4j-json-logger) |\n\n## Table of Contents\n\n\u003c!--ts--\u003e\n* [Getting started](#getting-started)\n* [Usage](#usage)\n* [Configuration](#configuration)\n* [Setup a provider by a system property](#setup-a-provider-by-a-system-property)\n* [Other solutions](#other-solutions)\n* [Contributing](#contributing)\n* [History](#history)\n* [Authors and acknowledgment](#authors-and-acknowledgment)\n* [License](#license)\n\n\u003c!-- Created by https://github.com/ekalinin/github-markdown-toc --\u003e\n\u003c!-- Added by: r2, at: Sun Mar  2 03:34:06 PM EET 2025 --\u003e\n\n\u003c!--te--\u003e\n\n## Getting started\n\nYet another SLF4J Simple, isn't it?\n\nNo, it isn't.\n\nThis implementation supports [MDC][mdc] to print out **AWS request ID**\nin start of every logging record and supports [Markers][marker] too.\nAnd the killer feature: it solves\nthe [CRLF issue](https://twitter.com/ben11kehoe/status/1264597451010433025)\ndescribed by Frank Afriat in\n[Solving the Java Aws Lambda logging problem][aws-lambda-logging-problem] -\nyou don't have to prepare logging messages\nand stacktraces to log them on CloudWatch Logs.\n\nThe footprint of **aws-lambda-slf4j-logger** (36K)\nand **aws-lambda-slf4j-json-logger** (116K) are the same as **slf4j-simple** (16K)\nand much smaller than **logback** (888K).\n\n### Usage\n\nThere is a great original [manual][manual].\n\nThe sample code:\n\n```java\n\n@Override\npublic String handleRequest(Map\u003cString, Object\u003e input, Context context) {\n  MDC.put(\"@aws-request-id@\", context.getAwsRequestId());\n\n  logger.trace(\"trace message\");\n  logger.debug(\"debug message\");\n  logger.info(\"info message\");\n  logger.warn(\"warning message\");\n  logger.error(\"error message\");\n\n  var marker = new BasicMarkerFactory().getMarker(\"important\");\n\n  Stream.of(\"\\n\", \"\\r\\n\", \"\\r\").forEach(injection -\u003e {\n    logger.trace(marker, \"CRLF{}injection\", injection);\n  });\n\n  logger.warn(\"printable stacktrace\", new Throwable(\"Printable Stacktrace Demo\"));\n  return \"done\";\n}\n```\n\nThe log with **aws-lambda-slf4j-logger**:\n\n```log\n983f71e5-9091-443b-8c01-6668120c0e5d INFO io.github.vitalijr2.slf4j_demo.BotHandler - info message\n983f71e5-9091-443b-8c01-6668120c0e5d WARN io.github.vitalijr2.slf4j_demo.BotHandler - warning message\n983f71e5-9091-443b-8c01-6668120c0e5d ERROR io.github.vitalijr2.slf4j_demo.BotHandler - error message\n983f71e5-9091-443b-8c01-6668120c0e5d TRACE io.github.vitalijr2.slf4j_demo.BotHandler - CRLF\ninjection\n983f71e5-9091-443b-8c01-6668120c0e5d TRACE io.github.vitalijr2.slf4j_demo.BotHandler - CRLF\ninjection\n983f71e5-9091-443b-8c01-6668120c0e5d TRACE io.github.vitalijr2.slf4j_demo.BotHandler - CRLF\ninjection\n983f71e5-9091-443b-8c01-6668120c0e5d WARN io.github.vitalijr2.slf4j_demo.BotHandler - printable stacktrace\n```\n\nThere is a JSON option with **aws-lambda-slf4j-json-logger**:\n\n```json\n{\n  \"level\": \"INFO\",\n  \"logname\": \"io.github.vitalijr2.slf4j_demo.BotHandler\",\n  \"message\": \"info message\",\n  \"aws-request-id\": \"7b9af47e-d861-44b4-bde7-fa2e84ffb7cf\"\n}\n{\n  \"level\": \"WARN\",\n  \"logname\": \"io.github.vitalijr2.slf4j_demo.BotHandler\",\n  \"message\": \"warning message\",\n  \"aws-request-id\": \"7b9af47e-d861-44b4-bde7-fa2e84ffb7cf\"\n}\n{\n  \"level\": \"ERROR\",\n  \"logname\": \"io.github.vitalijr2.slf4j_demo.BotHandler\",\n  \"message\": \"error message\",\n  \"aws-request-id\": \"7b9af47e-d861-44b4-bde7-fa2e84ffb7cf\"\n}\n{\n  \"level\": \"TRACE\",\n  \"logname\": \"io.github.vitalijr2.slf4j_demo.BotHandler\",\n  \"message\": \"CRLF\\ninjection\",\n  \"aws-request-id\": \"7b9af47e-d861-44b4-bde7-fa2e84ffb7cf\"\n}\n{\n  \"level\": \"TRACE\",\n  \"logname\": \"io.github.vitalijr2.slf4j_demo.BotHandler\",\n  \"message\": \"CRLF\\r\\ninjection\",\n  \"aws-request-id\": \"7b9af47e-d861-44b4-bde7-fa2e84ffb7cf\"\n}\n{\n  \"level\": \"TRACE\",\n  \"logname\": \"io.github.vitalijr2.slf4j_demo.BotHandler\",\n  \"message\": \"CRLF\\rinjection\",\n  \"aws-request-id\": \"7b9af47e-d861-44b4-bde7-fa2e84ffb7cf\"\n}\n{\n  \"stack-trace\": \"java.lang.Throwable: Printable Stacktrace Demo\\n\\tat io.github.vitalijr2.slf4j_demo.BotHandler.handleRequest(BotHandler.java:36)\\n\\tat io.github.vitalijr2.slf4j_demo.BotHandler.handleRequest(BotHandler.java:12)\\n\\tat lambdainternal.EventHandlerLoader$PojoHandlerAsStreamHandler.handleRequest(EventHandlerLoader.java:205)\\n\\tat lambdainternal.EventHandlerLoader$2.call(EventHandlerLoader.java:905)\\n\\tat lambdainternal.AWSLambda.startRuntime(AWSLambda.java:261)\\n\\tat lambdainternal.AWSLambda.startRuntime(AWSLambda.java:200)\\n\\tat lambdainternal.AWSLambda.main(AWSLambda.java:194)\\n\",\n  \"level\": \"WARN\",\n  \"logname\": \"io.github.vitalijr2.slf4j_demo.BotHandler\",\n  \"message\": \"printable stacktrace\",\n  \"aws-request-id\": \"7b9af47e-d861-44b4-bde7-fa2e84ffb7cf\"\n}\n```\n\n![CloudWatch logs](src/site/resources/cloudwatch-screenshot.png)\n\n### Configuration\n\nThe configuration is similar to [SLF4J Simple][slf4j-simple].\n\nIt looks for the `lambda-logger.properties` resource and read properties:\n\n* **dateTimeFormat** - The date and time format to be used\n  in the output messages. The pattern describing the date\n  and time format is defined by [SimpleDateFormat][]. If the format is not\n  specified or is invalid, the number of milliseconds since start up\n  will be output.\n* **defaultLogLevel** - Default log level for all instances of LambdaLogger.\n  Must be one of (_trace_, _debug_, _info_, _warn_, _error_),\n  a value is case-insensitive. If not specified, defaults to _info_.\n* **levelInBrackets** - Should the level string be output in brackets?\n  Defaults to `false`.\n* **log.a.b.c** - Logging detail level for a LambdaLogger instance\n  named _a.b.c_.\n* **requestId** - Set the context name of AWS request ID.\n  Defaults to `AWS_REQUEST_ID`.\n* **showDateTime** - Set to `true` if you want the current date\n  and time to be included in output messages. Defaults to `false`.\n* **showLogName** - Set to `true` if you want the Logger instance name\n  to be included in output messages. Defaults to `true`.\n* **showShortLogName** - Set to `true` if you want the last component\n  of the name to be included in output messages. Defaults to `false`.\n* **showThreadId** - If you would like to output the current thread id,\n  then set to `true`. Defaults to `false`.\n* **showThreadName** - Set to `true` if you want to output\n  the current thread name. Defaults to `false`.\n\nThe environment variables overrides the properties: **LOG_AWS_REQUEST_ID**,\n**LOG_DATE_TIME_FORMAT**, **LOG_DEFAULT_LEVEL**, **LOG_LEVEL_IN_BRACKETS**,\n**LOG_SHOW_DATE_TIME**, **LOG_SHOW_NAME**, **LOG_SHOW_SHORT_NAME**,\n**LOG_SHOW_THREAD_ID**, **LOG_SHOW_THREAD_NAME**.\n\n### Setup a provider by a system property\n\n[SLF4J 2.0.9][slf4j.provider] allows a provider to be explicitly specified.\nSince AWS Lambda Environment does not provide any configuration options\nto set what options should be used on startup,\nthe [trick is to use the JAVA_TOOL_OPTIONS][java-tool-options-trick]\nenvironment variable.\n\nIf your AWS Java Lambda has some SLF4J providers and you want\nto point one of them, that needs to setup a System property\nnamed `slf4j.provider`, as in the following:\n\n![Using JAVA_TOOL_OPTIONS to setup a provider](src/site/resources/environment-variable-screenshot.png)\n\n## Other solutions\n\nOther AWS centric loggers are [SLF4J/Logback Appender][awslambda-logback],\n[slf4j-simple-lambda][], Logback's [CloudWatch appender][cloudwatch-appender]\nand [CloudWatchLogs Java appender][cloudwatchlogs-java-appender].\n\n## Contributing\n\nPlease read [Contributing](contributing.md).\n\n## History\n\nSee [Changelog](changelog.md)\n\n## Authors and acknowledgment\n\n* Replace the custom output to stdout with AWS LambdaLogger, the main idea from\n  @igorakkerman [SLF4J/Logback Appender][awslambda-logback].\n\n## License\n\n```text\nCopyright (C) 2022 Vitalij Berdinskih\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n     https://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n\nSee full text [here](LICENSE \"the LICENSE file\").\n\n[SLF4J]: https://www.slf4j.org/\n\n[lambda]: https://aws.amazon.com/lambda/\n\n[cloudwatch]: https://aws.amazon.com/cloudwatch/\n\n[github-master-check-runs]: https://img.shields.io/github/check-runs/vitalijr2/aws-lambda-slf4j/main\n\n[github-master-check-runs-link]: https://github.com/vitalijr2/aws-lambda-slf4j/actions?query=branch%3Amain\n\n[codacy-badge]: https://app.codacy.com/project/badge/Grade/2c7cc1b8f6d7491283e13447594fdd82\n\n[codacy-badge-link]: https://app.codacy.com/gh/vitalijr2/aws-lambda-slf4j/dashboard?utm_source=gh\u0026utm_medium=referral\u0026utm_content=\u0026utm_campaign=Badge_grade\n\n[codacy-coverage]: https://app.codacy.com/project/badge/Coverage/2c7cc1b8f6d7491283e13447594fdd82\n\n[codacy-coverage-link]: https://app.codacy.com/gh/vitalijr2/aws-lambda-slf4j/dashboard?utm_source=gh\u0026utm_medium=referral\u0026utm_content=\u0026utm_campaign=Badge_coverage\n\n[github-commit-activity]: https://img.shields.io/github/commit-activity/y/vitalijr2/aws-lambda-slf4j\n\n[today-hits]: https://hits.sh/github.com/vitalijr2/vitalijr2/aws-lambda-slf4j.svg?view=today-total\u0026label=today's%20hits\n\n[today-hits-link]: https://hits.sh/github.com/vitalijr2/vitalijr2/aws-lambda-slf4j/\n\n[java-version]: https://img.shields.io/static/v1?label=java\u0026message=11\u0026color=blue\u0026logo=java\u0026logoColor=E23D28\n\n[jdk-download]: https://www.oracle.com/java/technologies/javase-jdk11-downloads.html\n\n[mdc]: https://www.slf4j.org/manual.html#mdc \"Mapped Diagnostic Context (MDC)\"\n\n[marker]: https://www.slf4j.org/apidocs/org/slf4j/Marker.html\n\n[aws-lambda-logging-problem]: https://frank-afriat.medium.com/solving-the-java-aws-lambda-logging-problem-305b06df457f \"Solving the Java Aws Lambda logging problem\"\n\n[manual]: https://www.slf4j.org/manual.html \"SLF4J user manual\"\n\n[slf4j-simple]: https://www.slf4j.org/api/org/slf4j/simple/SimpleLogger.html\n\n[SimpleDateFormat]: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/text/SimpleDateFormat.html\n\n[slf4j.provider]: https://jira.qos.ch/browse/SLF4J-450 \"[SLF4J-450]: Allow binding to be explicitly specified\"\n\n[java-tool-options-trick]: https://zenidas.wordpress.com/recipes/system-properties-for-a-java-lambda-function/ \"System properties for a Java Lambda function\"\n\n[awslambda-logback]: https://github.com/jlib-framework/jlib-awslambda-logback \"jlib AWS Lambda SLF4J/Logback Appender\"\n\n[slf4j-simple-lambda]: https://github.com/microlam-io/slf4j-simple-lambda\n\n[cloudwatch-appender]: https://github.com/sndyuk/logback-more-appenders \"Logback more appenders\"\n\n[cloudwatchlogs-java-appender]: https://github.com/boxfuse/cloudwatchlogs-java-appender\n\n[license-badge]: https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat\n\n[license-link]: https://www.apache.org/licenses/LICENSE-2.0.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvitalijr2%2Faws-lambda-slf4j","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvitalijr2%2Faws-lambda-slf4j","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvitalijr2%2Faws-lambda-slf4j/lists"}