[{"data":1,"prerenderedAt":149},["ShallowReactive",2],{"content-svc-lambda-paved-path-java-replatforming-observability-and-logging":3},{"markdown":4,"frontMatterAttributes":5,"bodyRaw":14,"menu":15,"menuType":145,"isCollapseableMenu":18,"nextDocItem":114,"previousDocItem":87,"contributorPaths":146,"contentName":148,"slug":110,"readingTime":107},"\u003Cp>\u003Cstrong>Observability\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>AWS Lambda is a serverless compute platform that automatically scales horizontally as the traffic to your function increases. The environments created by Lambda to run your code are secured to allow access only via the invoke API method. This means that if you previously accessed information about your application via an HTTP endpoint, it will not be possible with Lambda. This changes the tooling that we can use to implement observability practices.\u003C\u002Fp>\n\u003Cp>Lambda also doesn&#39;t allow you to run processes outside of the APIs and controls provided. You can&#39;t run a third-party process in the background like you might on a VM or a container. Instead, Lambda provides APIs to access function telemetry and logging data. Third parties such as Datadog, Hashicorp, and many others have written integrations for these APIs so that you don&#39;t have to.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Logging\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>Lambda functions run in execution environments that are ephemeral and can be terminated between invokes. Your application logging should know this and process your logging in a way that means that you are not losing logs if an environment is terminated.\u003C\u002Fp>\n\u003Cp>Applications that have previously logged to file systems and then had a separate process to send these logs to a central place won&#39;t work in Lambda. Instead, your Lambda function should follow output logs to stdout and the processing and routing of those logs should be handled by Lambda and the resources you&#39;ve configured.\u003C\u002Fp>\n\u003Cp> For example, if your application is using Log4J or Logback with a file appender you should change this instead log to stdout\u003C\u002Fp>\n\u003Cp> An example Log4J file appender configuration\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-xml\">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\n&lt;Configuration status=&quot;warn&quot; name=&quot;MyApp&quot; packages=&quot;&quot;&gt;\n    &lt;Appenders&gt;\n        &lt;File name=&quot;MyFile&quot; fileName=&quot;logs\u002Fapp.log&quot;&gt;\n            &lt;PatternLayout&gt;\n                &lt;Pattern&gt;%d %p %c{1.} [%t] %m%n&lt;\u002FPattern&gt;\n            &lt;\u002FPatternLayout&gt;\n        &lt;\u002FFile&gt;\n        &lt;Async name=&quot;Async&quot;&gt;\n            &lt;AppenderRef ref=&quot;MyFile&quot;\u002F&gt;\n        &lt;\u002FAsync&gt;\n    &lt;\u002FAppenders&gt;\n    &lt;Loggers&gt;\n        &lt;Root level=&quot;error&quot;&gt;\n            &lt;AppenderRef ref=&quot;Async&quot;\u002F&gt;\n        &lt;\u002FRoot&gt;\n    &lt;\u002FLoggers&gt;\n&lt;\u002FConfiguration&gt;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>An example Log4J stdout appender configuration\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-xml\">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;\n&lt;Configuration status=&quot;warn&quot; name=&quot;MyApp&quot; packages=&quot;&quot;&gt;\n    &lt;Appenders&gt;\n        &lt;Console name=&quot;STDOUT&quot; target=&quot;SYSTEM_OUT&quot;&gt;\n            &lt;PatternLayout&gt;\n                &lt;Pattern&gt;%d %p %c{1.} [%t] %m%n&lt;\u002FPattern&gt;\n            &lt;\u002FPatternLayout&gt;\n        &lt;\u002FConsole&gt;\n    &lt;\u002FAppenders&gt;\n    &lt;Loggers&gt;\n        &lt;Root level=&quot;error&quot;&gt;\n            &lt;AppenderRef ref=&quot;STDOUT&quot;\u002F&gt;\n        &lt;\u002FRoot&gt;\n    &lt;\u002FLoggers&gt;\n&lt;\u002FConfiguration&gt;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Cstrong>Centralized Logging\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Cloud Native logging with CloudWatch Logs\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>By default all messages that are written to stdout are saved to an Amazon CloudWatch log stream. Each Lambda function has its own log stream. \u003Ca href=\"https:\u002F\u002Faws.amazon.com\u002Fcloudwatch\u002Fpricing\u002F\">CloudWatch is billed\u003C\u002Fa> by the amount of data ingested, and the amount of storage used. The less logging your application produces the less you will be charged. By default log streams are kept indefinitely, this can be configured to a specific duration based on your requirements.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Logging to a third party\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>If you have a preferred logging solution that you would like to continue to use, you can most likely use an \u003Ca href=\"https:\u002F\u002Fdocs.aws.amazon.com\u002Flambda\u002Flatest\u002Fdg\u002Fextensions-api-partners.html\">existing integration\u003C\u002Fa>. Popular service providers such as Splunk, Datadog, Dynatrace, New Relic, Honeycomb, and many others have created integrations for you to use to make your Lambda logs available in their solutions.\u003C\u002Fp>\n\u003Cp>Lambda Partners use the Lambda \u003Ca href=\"https:\u002F\u002Fdocs.aws.amazon.com\u002Flambda\u002Flatest\u002Fdg\u002Ftelemetry-api.html\">Telemetry API\u003C\u002Fa> to take the logs produced to stdout by your function and direct them to their own service.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>General guidance\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>You should use CloudWatch Logs if you don&#39;t have an existing preferred logging solution. If this doesn&#39;t meet all of your requirements, and the solution you&#39;ve selected has an existing integration, use that. If the solution doesn&#39;t have an existing integration, then you will have to create your own. Your integration will have to work within the constraints of the Lambda execution environment.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Logging to multiple files\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>In the previous sections, you learned about how the Lambda execution model restricts how logging can be implemented. If your application writes separate information to different log files, for example a log with only error messages and a log with all messages. Then your application must change in order to adapt to the Lambda environment.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>General guidance\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>CloudWatch has powerful search functionality called \u003Ca href=\"https:\u002F\u002Fdocs.aws.amazon.com\u002FAmazonCloudWatch\u002Flatest\u002Flogs\u002FAnalyzingLogData.html\">CloudWatch Logs Insights\u003C\u002Fa> that you can use to filter for specific log messages. Where possible use a single log stream for each Lambda function and search for the data required. This will reduce the overall complexity of your Lambda function.\u003C\u002Fp>\n\u003Cp>If you need to have a separate stream for some application data, then you can use the CloudWatch SDK to write specifically to that log stream using the \u003Ca href=\"https:\u002F\u002Fdocs.aws.amazon.com\u002FAmazonCloudWatchLogs\u002Flatest\u002FAPIReference\u002FAPI_PutLogEvents.html\">PutLogEvents\u003C\u002Fa> API call. You can find a \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fawsdocs\u002Faws-doc-sdk-examples\u002Fblob\u002Fmain\u002Fjavav2\u002Fexample_code\u002Fcloudwatch\u002Fsrc\u002Fmain\u002Fjava\u002Fcom\u002Fexample\u002Fcloudwatch\u002FPutLogEvents.java\">Java example\u003C\u002Fa> in the aws-doc-sdk-examples project on GitHub.\u003C\u002Fp>\n",{"title":6,"order":7,"callout":8,"learningGoals":12},"Observability - Logging",2,{"title":9,"description":10,"link":11},"Workshop","The workshop gives you a step-by-step guide of how to migrate a Spring Boot application to Lambda using the AWS Serverless Java Container library.","https:\u002F\u002Fcatalog.workshops.aws\u002Fjava-on-aws-lambda\u002Fen-US\u002F01-migration",[13],"How to meet your logging requirements with Lambda","**Observability**\n\nAWS Lambda is a serverless compute platform that automatically scales horizontally as the traffic to your function increases. The environments created by Lambda to run your code are secured to allow access only via the invoke API method. This means that if you previously accessed information about your application via an HTTP endpoint, it will not be possible with Lambda. This changes the tooling that we can use to implement observability practices.\n\nLambda also doesn't allow you to run processes outside of the APIs and controls provided. You can't run a third-party process in the background like you might on a VM or a container. Instead, Lambda provides APIs to access function telemetry and logging data. Third parties such as Datadog, Hashicorp, and many others have written integrations for these APIs so that you don't have to.\n\n**Logging**\n\nLambda functions run in execution environments that are ephemeral and can be terminated between invokes. Your application logging should know this and process your logging in a way that means that you are not losing logs if an environment is terminated.\n\nApplications that have previously logged to file systems and then had a separate process to send these logs to a central place won't work in Lambda. Instead, your Lambda function should follow output logs to stdout and the processing and routing of those logs should be handled by Lambda and the resources you've configured.\n\n For example, if your application is using Log4J or Logback with a file appender you should change this instead log to stdout\n\n An example Log4J file appender configuration\n\n```xml\n\u003C?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\u003CConfiguration status=\"warn\" name=\"MyApp\" packages=\"\">\n    \u003CAppenders>\n        \u003CFile name=\"MyFile\" fileName=\"logs\u002Fapp.log\">\n            \u003CPatternLayout>\n                \u003CPattern>%d %p %c{1.} [%t] %m%n\u003C\u002FPattern>\n            \u003C\u002FPatternLayout>\n        \u003C\u002FFile>\n        \u003CAsync name=\"Async\">\n            \u003CAppenderRef ref=\"MyFile\"\u002F>\n        \u003C\u002FAsync>\n    \u003C\u002FAppenders>\n    \u003CLoggers>\n        \u003CRoot level=\"error\">\n            \u003CAppenderRef ref=\"Async\"\u002F>\n        \u003C\u002FRoot>\n    \u003C\u002FLoggers>\n\u003C\u002FConfiguration>\n```\nAn example Log4J stdout appender configuration\n\n```xml\n\u003C?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\u003CConfiguration status=\"warn\" name=\"MyApp\" packages=\"\">\n    \u003CAppenders>\n        \u003CConsole name=\"STDOUT\" target=\"SYSTEM_OUT\">\n            \u003CPatternLayout>\n                \u003CPattern>%d %p %c{1.} [%t] %m%n\u003C\u002FPattern>\n            \u003C\u002FPatternLayout>\n        \u003C\u002FConsole>\n    \u003C\u002FAppenders>\n    \u003CLoggers>\n        \u003CRoot level=\"error\">\n            \u003CAppenderRef ref=\"STDOUT\"\u002F>\n        \u003C\u002FRoot>\n    \u003C\u002FLoggers>\n\u003C\u002FConfiguration>\n```\n\n**Centralized Logging**\n\n**Cloud Native logging with CloudWatch Logs**\n\nBy default all messages that are written to stdout are saved to an Amazon CloudWatch log stream. Each Lambda function has its own log stream. [CloudWatch is billed](https:\u002F\u002Faws.amazon.com\u002Fcloudwatch\u002Fpricing\u002F) by the amount of data ingested, and the amount of storage used. The less logging your application produces the less you will be charged. By default log streams are kept indefinitely, this can be configured to a specific duration based on your requirements.\n\n**Logging to a third party**\n\nIf you have a preferred logging solution that you would like to continue to use, you can most likely use an [existing integration](https:\u002F\u002Fdocs.aws.amazon.com\u002Flambda\u002Flatest\u002Fdg\u002Fextensions-api-partners.html). Popular service providers such as Splunk, Datadog, Dynatrace, New Relic, Honeycomb, and many others have created integrations for you to use to make your Lambda logs available in their solutions.\n\nLambda Partners use the Lambda [Telemetry API](https:\u002F\u002Fdocs.aws.amazon.com\u002Flambda\u002Flatest\u002Fdg\u002Ftelemetry-api.html) to take the logs produced to stdout by your function and direct them to their own service.\n\n**General guidance**\n\nYou should use CloudWatch Logs if you don't have an existing preferred logging solution. If this doesn't meet all of your requirements, and the solution you've selected has an existing integration, use that. If the solution doesn't have an existing integration, then you will have to create your own. Your integration will have to work within the constraints of the Lambda execution environment.\n\n**Logging to multiple files**\n\nIn the previous sections, you learned about how the Lambda execution model restricts how logging can be implemented. If your application writes separate information to different log files, for example a log with only error messages and a log with all messages. Then your application must change in order to adapt to the Lambda environment.\n\n**General guidance**\n\nCloudWatch has powerful search functionality called [CloudWatch Logs Insights](https:\u002F\u002Fdocs.aws.amazon.com\u002FAmazonCloudWatch\u002Flatest\u002Flogs\u002FAnalyzingLogData.html) that you can use to filter for specific log messages. Where possible use a single log stream for each Lambda function and search for the data required. This will reduce the overall complexity of your Lambda function.\n\nIf you need to have a separate stream for some application data, then you can use the CloudWatch SDK to write specifically to that log stream using the [PutLogEvents](https:\u002F\u002Fdocs.aws.amazon.com\u002FAmazonCloudWatchLogs\u002Flatest\u002FAPIReference\u002FAPI_PutLogEvents.html) API call. You can find a [Java example](https:\u002F\u002Fgithub.com\u002Fawsdocs\u002Faws-doc-sdk-examples\u002Fblob\u002Fmain\u002Fjavav2\u002Fexample_code\u002Fcloudwatch\u002Fsrc\u002Fmain\u002Fjava\u002Fcom\u002Fexample\u002Fcloudwatch\u002FPutLogEvents.java) in the aws-doc-sdk-examples project on GitHub.\n",[16,36,55,84,101,111,135],{"title":17,"collapsible":18,"isCollapsed":19,"content":20},"Introduction",false,true,[21],{"title":17,"order":22,"callout":23,"prerequisite":24,"resources":27,"time":32,"path":33,"id":34,"link":35},1,{"title":9,"description":10,"link":11},[25,26],"Some understanding of Java","Some Understanding of AWS Lambda",[28],{"link":29,"text":30,"type":31},"https:\u002F\u002Faws.amazon.com\u002Flambda\u002F","Learn more about Lambda","text","2 min","introduction","introduction.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fpaved-path\u002Fjava-replatforming\u002Fintroduction",{"title":37,"collapsible":18,"isCollapsed":19,"content":38},"Access patterns",[39],{"title":40,"order":7,"callout":41,"resources":42,"learningGoals":50,"time":32,"path":52,"id":53,"link":54},"Access Patterns",{"title":9,"description":10,"link":11},[43,47],{"link":44,"type":45,"text":46},"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Faws-lambda-web-adapter","Repo","AWS Lambda Web Adapter",{"link":48,"text":49,"type":45},"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Faws-serverless-java-container","AWS Serverless Java Container",[51],"To learn the different approaches to replatforming REST APIs on Lambda","access-patterns","access-patterns.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fpaved-path\u002Fjava-replatforming\u002Faccess-patterns",{"title":56,"collapsible":18,"isCollapsed":19,"content":57},"SnapStart",[58],{"title":59,"youtubeVideoID":60,"order":7,"callout":61,"resources":64,"learningGoals":79,"time":32,"path":81,"id":82,"link":83},"Performance - SnapStart","ZbnAithBNYY",{"title":9,"description":62,"link":63},"Learn how SnapStart addresses Java function performance, how to enable SnapStart with IaC, and how to customize your SnapStart behavior with runtime hooks.","https:\u002F\u002Fcatalog.workshops.aws\u002Fjava-on-aws-lambda\u002Fen-US\u002F03-snapstart",[65,69,72,76],{"link":66,"text":67,"type":68},"https:\u002F\u002Fserverlessland.com\u002Fpatterns\u002Fapigw-lambda-snapstart","API Gateway to Lambda with SnapStart","Pattern",{"link":70,"type":68,"text":71},"https:\u002F\u002Fserverlessland.com\u002Fpatterns\u002Fapigw-lambda-rds-snapstart","REST API with Amazon API Gateway, Amazon RDS and AWS Lambda with SnapStart",{"link":73,"type":74,"text":75},"https:\u002F\u002Faws.amazon.com\u002Fblogs\u002Fcompute\u002Fstarting-up-faster-with-aws-lambda-snapstart\u002F?ref=serverlessland","Blog","Starting up faster with AWS Lambda SnapStart",{"link":77,"type":74,"text":78},"https:\u002F\u002Faws.amazon.com\u002Fblogs\u002Fcompute\u002Freducing-java-cold-starts-on-aws-lambda-functions-with-snapstart\u002F?ref=serverlessland","Reducing Java cold starts on AWS Lambda functions with SnapStart",[80],"Learn how Lambda SnapStart improves first invoke latency","snapstart","snapstart.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fpaved-path\u002Fjava-replatforming\u002Fsnapstart",{"title":85,"collapsible":18,"isCollapsed":19,"content":86},"Performance",[87],{"title":85,"youtubeVideoID":88,"order":7,"callout":89,"resources":91,"learningGoals":95,"time":97,"path":98,"id":99,"link":100},"sVJOJUD0fhQ",{"title":9,"description":90,"link":11},"Learn how to optimize Java Lambda functions.",[92],{"link":93,"type":74,"text":94},"https:\u002F\u002Faws.amazon.com\u002Fblogs\u002Fcompute\u002Foptimizing-aws-lambda-function-performance-for-java\u002F?ref=serverlessland","Optimizing AWS Lambda function performance for Java",[96],"How to optimization your Java function","1 min","performance","performance.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fpaved-path\u002Fjava-replatforming\u002Fperformance",{"title":102,"collapsible":18,"isCollapsed":18,"content":103},"Observability - Logging ",[104],{"title":6,"order":7,"callout":105,"learningGoals":106,"time":107,"path":108,"id":109,"link":110},{"title":9,"description":10,"link":11},[13],"4 min","observability-and-logging","observability-and-logging.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fpaved-path\u002Fjava-replatforming\u002Fobservability-and-logging",{"title":112,"collapsible":18,"isCollapsed":19,"content":113},"Observability - Metrics",[114],{"title":112,"order":7,"callout":115,"resources":119,"learningGoals":129,"time":131,"path":132,"id":133,"link":134},{"title":116,"description":117,"link":118},"Watch the video","AWS Lambda Powertools: Lessons from the road to 10 million downloads.","https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=dH2GP6Lydj8",[120,123,126],{"link":121,"text":122,"type":45},"https:\u002F\u002Fawslabs.github.io\u002Faws-lambda-powertools-java\u002Fcore\u002Fmetrics\u002F","Lambda Powertools for Java - Metrics",{"link":124,"text":125,"type":45},"https:\u002F\u002Fawslabs.github.io\u002Faws-lambda-powertools-java\u002F","Lambda Powertools for Java",{"link":127,"text":128,"type":45},"https:\u002F\u002Fgithub.com\u002Fawslabs\u002Faws-embedded-metrics-java","EMF Client Library",[130],"How to efficiently write metrics with Lambda","3 min","metrics","metrics.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fpaved-path\u002Fjava-replatforming\u002Fmetrics",{"title":136,"collapsible":18,"isCollapsed":19,"content":137},"Health checks",[138],{"title":139,"order":7,"learningGoals":140,"time":97,"path":142,"id":143,"link":144},"Health Checks",[141],"To understand when to use health checks with Lambda","health-checks","health-checks.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fpaved-path\u002Fjava-replatforming\u002Fhealth-checks","LESSON",[147],"content\u002Fcontributors\u002Fmark-sailes.json","Java Replatforming",1792665273861]