<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: James Miller</title>
    <description>The latest articles on DEV Community by James Miller (@millerjam).</description>
    <link>https://dev.to/millerjam</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F825525%2Fd9fdc180-3b7e-4c0d-b10d-7002fb886258.jpeg</url>
      <title>DEV Community: James Miller</title>
      <link>https://dev.to/millerjam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/millerjam"/>
    <language>en</language>
    <item>
      <title>Rust Lambda Hello World Tests</title>
      <dc:creator>James Miller</dc:creator>
      <pubDate>Sun, 27 Mar 2022 13:09:17 +0000</pubDate>
      <link>https://dev.to/millerjam/rust-lambda-hello-world-tests-3ikl</link>
      <guid>https://dev.to/millerjam/rust-lambda-hello-world-tests-3ikl</guid>
      <description>&lt;p&gt;This is my third and final post in this series about getting started with writing Lambda's in Rust. So far, we have created a new lambda, cross compiled it to run in the AWS Lamdba environment, and added some logging so we can debug issues and see how the code is executing.&lt;/p&gt;

&lt;p&gt;In this final post, we will add tests and setup Github Actions to verify these test on any Pull Request.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can check out the previous posts here&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://millerjam.github.io/posts/rust-lambda-hello-world/"&gt;https://millerjam.github.io/posts/rust-lambda-hello-world/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://millerjam.github.io/posts/rust-lambda-hello-world-logging/"&gt;https://millerjam.github.io/posts/rust-lambda-hello-world-logging/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Let's add a test
&lt;/h2&gt;

&lt;p&gt;Now that we have some code and logging in place, there is one final thing I want to cover before we could consider adding more code. We should quickly look at how to test this code.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://github.com/awslabs/aws-lambda-rust-runtime"&gt;AWS Lambda Rust Runtime&lt;/a&gt; makes it easy to test your handler code. When we look at the existing &lt;a href="https://github.com/millerjam/rust_lambda_hello_world/blob/dc13198be3c2520d41cfd91dd87d2a3139d5b9c2/src/main.rs#L7-L12"&gt;&lt;code&gt;main()&lt;/code&gt; method&lt;/a&gt; we see that we are just registering our handler function &lt;code&gt;func&lt;/code&gt; with the &lt;code&gt;lambda_runtime&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;This forces a nice decoupling between the code wiring up the lambda environment, and the business logic in the handler function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Business logic
&lt;/h3&gt;

&lt;p&gt;In the "hello world" example, the business logic is as follows:&lt;br&gt;
1) Check for a "firstName" value in the incoming event.&lt;br&gt;
2) If firstName is found, return "Hello, [firstName]!"&lt;br&gt;
3) If firstName is NOT found, return "Hello, world!"&lt;/p&gt;
&lt;h2&gt;
  
  
  Writing a test
&lt;/h2&gt;

&lt;p&gt;The easiest way to add test code, is to create the tests in the same file as the function we are trying to test.&lt;/p&gt;

&lt;p&gt;In our example we will add a new test directly in the &lt;code&gt;src/main.rs&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Here is the code we will add as the bottom of the file&lt;/p&gt;

&lt;p&gt;&lt;code&gt;main.rs&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[cfg(test)]&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;lambda_runtime&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;#[tokio::test]&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;test_func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;json!&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"James"&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LambdaEvent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"Hello, James!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may notice that we are using &lt;code&gt;#[tokio::test]&lt;/code&gt; and that the test itself is marked &lt;code&gt;async&lt;/code&gt;, this is because the lambda rust runtime is using the tokio framework and when testing async function we need to using these constructs.&lt;/p&gt;

&lt;p&gt;First, we create the test Event using a default &lt;code&gt;Context&lt;/code&gt;, and a JSON event with the proper field. Once we have created our test &lt;code&gt;event&lt;/code&gt;, we are able to use that as the payload to call our function &lt;code&gt;func(event)&lt;/code&gt;. We use the &lt;code&gt;await.unwrap()&lt;/code&gt; to get the result since our handler method &lt;code&gt;func&lt;/code&gt; is an async function.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;test_func&lt;/code&gt; itself is a "happy path" test, verifying that we will get the expected output when the "firstName" field is found in the event. The final step of the test is to assert that the returned value matches the expected "Hello, James!"&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding a second test
&lt;/h2&gt;

&lt;p&gt;Now that we covered the "happy path" logic, we should add one more test to cover the case when "firstName" is not found&lt;/p&gt;

&lt;p&gt;In the same &lt;code&gt;mod test&lt;/code&gt; block, we can add a second test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[tokio::test]&lt;/span&gt;
    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;test_func_bad_request&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;json!&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s"&gt;"something"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"wrong"&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LambdaEvent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s"&gt;"Hello, world!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This test follows the same format as the previous, with the difference being the &lt;code&gt;payload&lt;/code&gt; is updates with different JSON value. We expect that the handle will return "Hello, world!" in this case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running test
&lt;/h2&gt;

&lt;p&gt;Now that we have created some tests, lets run them with cargo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We should get output like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;running 2 tests
test tests::test_func_bad_request ... ok
test tests::test_func ... ok
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Success! We can see that cargo found the 2 tests, and both are passing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automating test with Github Actions
&lt;/h2&gt;

&lt;p&gt;Now that we can run tests locally, it would be nice to have them running automatically when we create a new PR for our project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding github actions
&lt;/h3&gt;

&lt;p&gt;This is really easy to setup, using &lt;a href="https://actions-rs.github.io/"&gt;actions-rs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This project provides a toolkit of GitHub Action for Rust projects.&lt;/p&gt;

&lt;p&gt;We need to create a &lt;code&gt;rust.yml&lt;/code&gt; file in &lt;code&gt;.github/workflows/rust.yml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The yaml file will contain "jobs" for the cargo commands &lt;code&gt;check&lt;/code&gt;, &lt;code&gt;test&lt;/code&gt;, &lt;code&gt;fmt&lt;/code&gt;, and &lt;code&gt;clippy&lt;/code&gt;. This will make sure that all PRs made against our repo, are properly formatted, have passing test, and passing all standard rust linting checks.&lt;/p&gt;

&lt;p&gt;The entire file is here&lt;br&gt;
&lt;a href="https://github.com/millerjam/rust_lambda_hello_world/blob/main/.github/workflows/rust.yml"&gt;https://github.com/millerjam/rust_lambda_hello_world/blob/main/.github/workflows/rust.yml&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One you have committed this file into your github repo, you will see it populated in the &lt;a href="https://github.com/millerjam/rust_lambda_hello_world/actions"&gt;"Action" tab&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="/gh-action-pass-1.png" class="article-body-image-wrapper"&gt;&lt;img src="/gh-action-pass-1.png" alt="GitHub Action Passing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Passing PRs will show a green check, and if any of the checks fail the PR will be marked as failed. And selecting the failed action will show the 4 jobs and which has failed&lt;/p&gt;

&lt;p&gt;&lt;a href="/gh-action-failed-2.png" class="article-body-image-wrapper"&gt;&lt;img src="/gh-action-failed-2.png" alt="GitHub Action Failed"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Now, we have a completed "hello world" lambda example. We created:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://millerjam.github.io/posts/rust-lambda-hello-world/#add-the-code"&gt;An hello world lambda function&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://millerjam.github.io/posts/rust-lambda-hello-world/#build-for-aws-lambda-install-x86-target"&gt;Cross compile the lambda&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://millerjam.github.io/posts/rust-lambda-hello-world/#package-and-create-the-lambda"&gt;Deployed it into AWS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://millerjam.github.io/posts/rust-lambda-hello-world-logging/#lets-add-some-logging"&gt;Added logging&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://millerjam.github.io/posts/rust-lambda-hello-world-tests/#writing-a-test"&gt;Added tests&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://millerjam.github.io/posts/rust-lambda-hello-world-tests/#adding-github-actions"&gt;And finally, added continuous integration with GitHub Actions&lt;/a&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Final GitHub Project
&lt;/h3&gt;

&lt;p&gt;You can reference the complete project here in my github repo &lt;a href="https://github.com/millerjam/rust_lambda_hello_world"&gt;https://github.com/millerjam/rust_lambda_hello_world&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Rust Lambda Hello World Logging</title>
      <dc:creator>James Miller</dc:creator>
      <pubDate>Sun, 13 Mar 2022 18:35:38 +0000</pubDate>
      <link>https://dev.to/millerjam/rust-lambda-hello-world-logging-4c1p</link>
      <guid>https://dev.to/millerjam/rust-lambda-hello-world-logging-4c1p</guid>
      <description>&lt;p&gt;In my previous article, I started a tutorial on creating a lambda in Rust. If you missed it, you can catch up on that article here -&amp;gt; &lt;a href="https://millerjam.github.io/posts/rust-lambda-hello-world/"&gt;Rust Lambda Hello World&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Lets add some logging
&lt;/h2&gt;

&lt;p&gt;Before we go much further with our Rust code, let's add some logging. We are take advantage of the &lt;a href="https://docs.rs/tracing/latest/tracing/"&gt;tracing library&lt;/a&gt; which is already integrated into many of the lambda dependencies.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Details about the tracing library are out of scope for this article, but you can learn more from the &lt;a href="https://docs.rs/tracing/latest/tracing/"&gt;tracing crate docs&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Init the logger
&lt;/h3&gt;

&lt;p&gt;Setting up the logger requires initializing the tracing subscriber library, the &lt;a href="https://github.com/awslabs/aws-lambda-rust-runtime/tree/v0.5.0/lambda-runtime/examples"&gt;AWS Lambda Rust Runtime Examples&lt;/a&gt; has a examples with some details about how to get started.&lt;/p&gt;

&lt;p&gt;Here is the code that we will have to add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;init_lambda_tracing&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;tracing_subscriber&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;        
        &lt;span class="nf"&gt;.with_max_level&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;tracing&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;Level&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;// this needs to be set to false, otherwise ANSI color codes will&lt;/span&gt;
        &lt;span class="c1"&gt;// show up in a confusing manner in CloudWatch logs.&lt;/span&gt;
        &lt;span class="nf"&gt;.with_ansi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;// disabling time is handy because CloudWatch will add the ingestion time.&lt;/span&gt;
        &lt;span class="nf"&gt;.without_time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I have created a small function &lt;code&gt;init_lambda_tracing()&lt;/code&gt; with all the details for setting up the logging. This function will setup the default &lt;code&gt;tracing_subscriber&lt;/code&gt; which prints logs to stdout. The additional methods called on the builder, set the default logging level to "info" and disable some of the defaults to make things nicer in the Lambda environment. Finally, I added additional code to the &lt;code&gt;main()&lt;/code&gt; to call this function before the lambda runtime setup.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fix the compile issues
&lt;/h3&gt;

&lt;p&gt;Even though we did not add any additional &lt;code&gt;import ...&lt;/code&gt; lines, we still need to add our new tracing library dependencies to &lt;code&gt;Cargo.toml&lt;/code&gt;, before our code will build.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The reason we did not add &lt;code&gt;import..&lt;/code&gt; statements is that we fully qualified the crate directly in the code with the prefix &lt;code&gt;tracing_subscriber::...&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Lets go ahead and add the 2 dependencies: &lt;a href="https://crates.io/crates/tracing"&gt;tracing&lt;/a&gt;, and &lt;a href="https://crates.io/crates/tracing-subscriber"&gt;tracing-subscriber&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo add tracing

cargo add tracing-subscriber
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Lets test it!
&lt;/h2&gt;

&lt;p&gt;Ok now that we have logging setup, let's add some logs and try it. The tracing library provides logging macros such as, &lt;code&gt;debug!&lt;/code&gt;, &lt;code&gt;info!&lt;/code&gt;, &lt;code&gt;warn!&lt;/code&gt;, &lt;code&gt;error!&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We will add an new "info" log  to the &lt;code&gt;func&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;info!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Going to say hello to {}!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will also need to import&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;tracing&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can update the function and test.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compile &amp;amp; update the function
&lt;/h3&gt;

&lt;p&gt;Just like in the previous article, we need to compile for the lambda env and update the function.&lt;/p&gt;

&lt;h4&gt;
  
  
  Compile
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo zigbuild --release --target x86_64-unknown-linux-gnu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Update the existing function
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws lambda update-function-code --function-name rustTest \
  --zip-file fileb://./lambda.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Test invoke &amp;amp; check the logs
&lt;/h2&gt;

&lt;p&gt;Now that the lambda is update with the new code, we can go ahead and test and check for our new logs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Invoke
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws lambda invoke \
  --cli-binary-format raw-in-base64-out \
  --function-name rustTest \
  --payload '{"firstName": "James"}' \
  output.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Now check the cloudwatch logs again
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;START RequestId: 93bcbe8c-4b2e-4af3-b00d-3b4b27083ebe Version: $LATEST
INFO lambda_test: going to say hello to James
END RequestId: 93bcbe8c-4b2e-4af3-b00d-3b4b27083ebe
REPORT RequestId: 93bcbe8c-4b2e-4af3-b00d-3b4b27083ebe  Duration: 1.16 ms   Billed Duration: 33 ms  Memory Size: 128 MB Max Memory Used: 17 MB  Init Duration: 31.20 ms 
XRAY TraceId: 1-622553a3-5644934610a4952626f10403   SegmentId: 3b7b79993cba7894 Sampled: true   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Success! We now have our log,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INFO lambda_test: going to say hello to James
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Reconfigure the logger
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Update the code for dynamic log levels
&lt;/h3&gt;

&lt;p&gt;Now that we have logging working, let's reconfigure it so that it reads the log level&lt;br&gt;
from an environment variable. This is will be much more flexible and give us the ability to turn logging levels up and down while we are developing and debugging, without having to recompile the code.&lt;/p&gt;

&lt;p&gt;We can update the &lt;code&gt;init_lambda_tracing&lt;/code&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;init_lambda_tracing&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;tracing_subscriber&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.with_env_filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;EnvFilter&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_default_env&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="c1"&gt;// this needs to be set to false, otherwise ANSI color codes will&lt;/span&gt;
        &lt;span class="c1"&gt;// show up in a confusing manner in CloudWatch logs.&lt;/span&gt;
        &lt;span class="nf"&gt;.with_ansi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;// disabling time is handy because CloudWatch will add the ingestion time.&lt;/span&gt;
        &lt;span class="nf"&gt;.without_time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;.init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We replaced the hardcoded &lt;code&gt;set_max_level...&lt;/code&gt; with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nf"&gt;.with_env_filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;EnvFilter&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_default_env&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this will read the logging level from the &lt;br&gt;
environment variable &lt;code&gt;RUST_LOG&lt;/code&gt;. Now we can change the log level dynamically without having the recompile and update the running code.&lt;/p&gt;

&lt;p&gt;We will also have to update the &lt;code&gt;Cargo.toml&lt;/code&gt; to make sure the "EnvFilter" feature is available from the &lt;code&gt;tracing_subscriber&lt;/code&gt; library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tracing-subscriber = {version = "0.3.9", features = ["env-filter"]}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Compile &amp;amp; update the function configuration
&lt;/h3&gt;

&lt;p&gt;Now that code is update, we need to rebuild, update the function, and then also the config&lt;br&gt;
to add the new &lt;code&gt;"RUST_LOG"&lt;/code&gt; environment variable. Let's set the logging level to "DEBUG" for testing.&lt;/p&gt;
&lt;h4&gt;
  
  
  Compile
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo zigbuild --release --target x86_64-unknown-linux-gnu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Update the existing function
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws lambda update-function-code --function-name rustTest \
  --zip-file fileb://./lambda.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Update the existing function configuration
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws lambda update-function-configuration \
    --function-name  rustTest \
    --environment Variables="{RUST_BACKTRACE=1,RUST_LOG=debug}"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Test invoke again
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws lambda invoke \
  --cli-binary-format raw-in-base64-out \
  --function-name rustTest \
  --payload '{"firstName": "James"}' \
  output.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Check the cloudwatch logs again
&lt;/h3&gt;

&lt;p&gt;Logs are much more verbose, we can see lots of new logs from the included dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;START RequestId: 9ebad5dc-3cee-4302-a0f8-0e592e432f41 Version: $LATEST
DEBUG hyper::client::connect::http: connecting to 127.0.0.1:9001
DEBUG hyper::client::connect::http: connected to 127.0.0.1:9001
DEBUG hyper::proto::h1::io: flushed 109 bytes
DEBUG hyper::proto::h1::io: parsed 7 headers
DEBUG hyper::proto::h1::conn: incoming body is content-length (21 bytes)
DEBUG hyper::proto::h1::conn: incoming body completed
DEBUG hyper::client::pool: pooling idle connection for ("http", 127.0.0.1:9001)
INFO lambda_test: going to say hello to James
DEBUG hyper::client::pool: reuse idle connection for ("http", 127.0.0.1:9001)
DEBUG hyper::proto::h1::io: flushed 198 bytes
DEBUG hyper::proto::h1::io: parsed 3 headers
DEBUG hyper::proto::h1::conn: incoming body is content-length (16 bytes)
DEBUG hyper::client::connect::http: connecting to 127.0.0.1:9001
DEBUG hyper::proto::h1::conn: incoming body completed
DEBUG hyper::client::pool: reuse idle connection for ("http", 127.0.0.1:9001)
DEBUG hyper::proto::h1::io: flushed 109 bytes
END RequestId: 9ebad5dc-3cee-4302-a0f8-0e592e432f41
REPORT RequestId: 9ebad5dc-3cee-4302-a0f8-0e592e432f41  Duration: 1.46 ms   Billed Duration: 38 ms  Memory Size: 128 MB Max Memory Used: 17 MB  Init Duration: 36.11 ms 
XRAY TraceId: 1-622551be-6d58480b496655162937c59c   SegmentId: 03a6c5576dc28250 Sampled: true   
DEBUG hyper::client::connect::http: connected to 127.0.0.1:9001
DEBUG hyper::client::pool: pooling idle connection for ("http", 127.0.0.1:9001)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;We were able to successfully add logging to our "hello world" lambda, and make it possible to dynamically change the logging level based on an environment variable. Using the tracing library made this easy, and the code is straight forward.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finally the Source Code
&lt;/h3&gt;

&lt;p&gt;The complete project is here in my github repo &lt;a href="https://github.com/millerjam/rust_lambda_hello_world"&gt;https://github.com/millerjam/rust_lambda_hello_world&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Time
&lt;/h2&gt;

&lt;p&gt;Next time, we will look at adding a unit test and finally try switching from building x86 to ARM for even more savings on our lambda executions. &lt;/p&gt;

</description>
      <category>rust</category>
      <category>serverless</category>
      <category>aws</category>
    </item>
    <item>
      <title>Rust Lambda Hello World</title>
      <dc:creator>James Miller</dc:creator>
      <pubDate>Mon, 07 Mar 2022 22:06:12 +0000</pubDate>
      <link>https://dev.to/millerjam/rust-lambda-hello-world-23d6</link>
      <guid>https://dev.to/millerjam/rust-lambda-hello-world-23d6</guid>
      <description>&lt;h2&gt;
  
  
  Getting started with AWS Lambda Rust Runtime
&lt;/h2&gt;

&lt;p&gt;I just finished a quick tutorial to create a &lt;a href="https://github.com/millerjam/rust_lambda_hello_world"&gt;hello world&lt;/a&gt; lambda using the &lt;a href="https://github.com/awslabs/aws-lambda-rust-runtime"&gt;AWS Lambda Rust Runtime&lt;/a&gt;&lt;/p&gt;




&lt;h4&gt;
  
  
  Github repo for the tutorial
&lt;/h4&gt;

&lt;p&gt;If you're in a rush...&lt;/p&gt;

&lt;p&gt;You can view the completed source code here: &lt;a href="https://github.com/millerjam/rust_lambda_hello_world"&gt;rust_lambda_hello_world&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;I think that Rust is a great fit for serverless and I wanted to start documenting how to use Rust in a lambda. Lambdas are a great opportunity to test out a new language without making a huge commitment in terms of time or resources. Additionally, the explicit connection between execution time and cost highlight the benefit of Rust's speed, both for for cold starts and  warm execution time.&lt;/p&gt;

&lt;p&gt;Before getting started here some prerequisites that you should already have working...&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Install rust/cargo/etc&lt;/li&gt;
&lt;li&gt;Code editor&lt;/li&gt;
&lt;li&gt;AWS Account&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Create a new rust binary
&lt;/h2&gt;

&lt;p&gt;Let's get started with creating a new rust binary&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo new lambda_test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here I am using &lt;code&gt;cargo&lt;/code&gt; to create a new binary with the name "lambda_test". This will create a new directory and create a scaffold of a rust project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;Now we are ready to get started writing our first lambda in rust. We will create a simple "hello world" lambda that will read an event that contains a first name, and respond with "Hello [first name]." Along the way we will cover writing the code, adding the crates, cross compiling for the lambda environment, deploying, and finally testing our code.&lt;/p&gt;

&lt;p&gt;Let's get started...&lt;/p&gt;

&lt;h2&gt;
  
  
  Add the code
&lt;/h2&gt;

&lt;p&gt;To make this easy, we'll copy the code from the &lt;a href="https://github.com/awslabs/aws-lambda-rust-runtime/tree/v0.5.0"&gt;AWS Lambda Rust Runtime&lt;/a&gt; README example. (Note: make sure you've selected the tag for version, v0.5 at the time I'm writing this) Copy the code snippet below, and replace the existing code in your project's &lt;code&gt;lambda_test/main.rs&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;lambda_runtime&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;service_fn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LambdaEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;serde_json&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nd"&gt;#[tokio::main]&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;service_fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nn"&gt;lambda_runtime&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;.await&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;LambdaEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="nf"&gt;.into_parts&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="nf"&gt;.as_str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.unwrap_or&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"world"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;json!&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, {}!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code has 2 methods. The &lt;code&gt;main()&lt;/code&gt; which initializes some lambda related scaffolding. And the &lt;code&gt;func(event: LambdaEvent&amp;lt;Value&amp;gt;)&lt;/code&gt; which is our code's handler function. This is where all the business logic for our lambda lives.&lt;/p&gt;

&lt;p&gt;You'll notice that the &lt;a href="https://github.com/awslabs/aws-lambda-rust-runtime/tree/v0.5.0"&gt;AWS Lambda Rust Runtime&lt;/a&gt; uses &lt;a href="https://tokio.rs/"&gt;tokio&lt;/a&gt; so the &lt;code&gt;main&lt;/code&gt; function is preceded with a tokio macro and our handler function &lt;code&gt;func&lt;/code&gt; needs to be &lt;code&gt;async&lt;/code&gt;. The details of tokio are out of scope for this article. For now it is enough to just know it is an async framework used in some rust projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fix the copy pasta errors
&lt;/h2&gt;

&lt;p&gt;Currently the lambda will not build, your IDE may show some errors related to crates not found.&lt;/p&gt;

&lt;p&gt;Lets update the &lt;code&gt;Cargo.toml&lt;/code&gt; with the required libraries.&lt;/p&gt;

&lt;p&gt;I use &lt;a href="https://github.com/killercup/cargo-edit"&gt;Cargo Edit&lt;/a&gt; which extends Cargo with commands to manage dependencies without having to manually edit your &lt;code&gt;Cargo.toml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo add lambda_runtime

cargo add serde_json

cargo add tokio
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we have added the &lt;a href="https://github.com/awslabs/aws-lambda-rust-runtime/tree/v0.5.0"&gt;AWS Lambda Rust Runtime&lt;/a&gt;, &lt;a href="https://github.com/serde-rs/json"&gt;Serde JSON&lt;/a&gt;, and &lt;a href="https://tokio.rs/"&gt;tokio&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, the project should be ready to build.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to build
&lt;/h2&gt;

&lt;p&gt;We will need to build a binary for the lambda environment, which might be different from our laptop. I'm using MacOS, so I'll need to cross compile. If you are using linux you might be able to build for our target architecture without these extra steps. You are are using a mac, you can follow along to add the zig linker and appropriate target for the Lambda environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check that normal local builds are working, and fix any dependency issues if needed.
&lt;/h3&gt;

&lt;p&gt;Before we get started with the cross compile steps, lets make sure a normal build works without and issues.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok that should succeed and let us know that the code and dependencies are correct.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build for AWS Lambda install x86 target
&lt;/h3&gt;

&lt;p&gt;We are going to target the "Amazon Linux2 x86" for our Lambda environment. In order to achieve this from a MacOS we will need to cross compile.  The &lt;a href="https://github.com/awslabs/aws-lambda-rust-runtime/tree/v0.5.0#1-cross-compiling-your-lambda-functions"&gt;AWS Lambda Rust Runtime&lt;/a&gt; Github repo has instructions for cross compiling that we will follow here. They use &lt;code&gt;zig&lt;/code&gt; and a cargo binary &lt;code&gt;zigbuild&lt;/code&gt; to accomplish the build process.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First install &lt;a href="https://ziglang.org/"&gt;Zig&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install zig
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install cargo &lt;a href="https://github.com/messense/cargo-zigbuild"&gt;zigbuild&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo install cargo-zigbuild
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add the target for x86
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rustup target add x86_64-unknown-linux-gnu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Finally, we build the release
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo zigbuild --release --target x86_64-unknown-linux-gnu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Package and Create the Lambda
&lt;/h2&gt;

&lt;p&gt;Ok, now we have a binary that we can run on the AWS Lambda infrastructure. Next step, we need to bundle the binary and upload to our AWS account.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a zip archive
&lt;/h3&gt;

&lt;p&gt;In order to install and test our lambda, we are going to create a zip file with the binary. The binary is expected to have the name &lt;code&gt;"bootstrap"&lt;/code&gt;, so the following command renames it and creates a zip file that is ready to be uploaded to AWS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cp ./target/x86_64-unknown-linux-gnu/release/lambda_test ./bootstrap &amp;amp;&amp;amp; zip lambda.zip bootstrap &amp;amp;&amp;amp; rm bootstrap
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create new function
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Note: Currently, I'm missing details about how to create the role and copy the ARN&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now that we have the zip file with the "bootstrap" binary, we are ready to create a new lambda function.  In the following command we use the &lt;code&gt;aws&lt;/code&gt; cli to create a new lambda function with the name "rustTest".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws lambda create-function --function-name rustTest \
  --handler doesnt.matter \
  --zip-file fileb://./lambda.zip \
  --runtime provided.al2 \
  --role arn:aws:iam::{PUT_AWS_ACCT}:role/lambda_basic_execution \
  --environment Variables={RUST_BACKTRACE=1} \
  --tracing-config Mode=Active
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Note&lt;/code&gt; you will need to modify this command with your own &lt;code&gt;"--role"&lt;/code&gt; name including account number.&lt;/p&gt;

&lt;p&gt;Once we have run this command the new rust lambda function exists in our AWS account and we are ready to run a test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test and Check the logs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Test invoke
&lt;/h3&gt;

&lt;p&gt;We can invoke for testing directly from the cli using this cli command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws lambda invoke \
  --cli-binary-format raw-in-base64-out \
  --function-name rustTest \
  --payload '{"firstName": "James"}' \
  output.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Check output
&lt;/h3&gt;

&lt;p&gt;The output of the lambda is written to a file specified in the "invoke" command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt; cat output.json
{"message":"Hello, James!"}%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Check logs
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Note: would be good to add how to check cloudwatch logs from cli&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After invoking our "rustTest" lambda, we will want to check the cloudwatch logs and see the execution time.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;START RequestId: 2b0a5ad0
Version: $LATEST
END RequestId: 2b0a5ad0
REPORT RequestId: 2b0a5ad0  Duration: 0.85 ms   Billed Duration: 1 ms   Memory Size: 128 MB Max Memory Used: 15 MB  
XRAY TraceId: 1-6213be54    SegmentId: 282cd    Sampled: true   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The "hello world" lambda doesn't do much, but it is still impressive to see a &lt;code&gt;Billed Duration: 1 ms&lt;/code&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;We were able to successfully create a Lambda using Rust! Using the &lt;a href="https://github.com/awslabs/aws-lambda-rust-runtime"&gt;AWS Lambda Rust Runtime&lt;/a&gt; made this easy, the code is straight forward. And using Zig made it easy to cross compile. The final result is a small binary that runs super fast.&lt;/p&gt;

&lt;h4&gt;
  
  
  Finally the Source Code
&lt;/h4&gt;

&lt;p&gt;The complete project is here in my github repo &lt;a href="https://github.com/millerjam/rust_lambda_hello_world"&gt;https://github.com/millerjam/rust_lambda_hello_world&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Time
&lt;/h2&gt;

&lt;p&gt;Next time, we will look at moving past "hello world" by adding some more functionality that we would need for any real world projects. &lt;/p&gt;

</description>
      <category>rust</category>
      <category>serverless</category>
      <category>aws</category>
    </item>
    <item>
      <title>My First Post</title>
      <dc:creator>James Miller</dc:creator>
      <pubDate>Tue, 22 Feb 2022 16:09:05 +0000</pubDate>
      <link>https://dev.to/millerjam/my-first-post-161j</link>
      <guid>https://dev.to/millerjam/my-first-post-161j</guid>
      <description>&lt;p&gt;I started learning Serverless with &lt;a href="https://www.rust-lang.org/"&gt;Rust&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is a quick tutorial I started creating, &lt;a href="https://github.com/millerjam/rust_lambda_hello_world"&gt;rust_lambda_hello_world&lt;/a&gt;. This is a simple "hello world" lambda that uses the &lt;a href="https://github.com/awslabs/aws-lambda-rust-runtime"&gt;AWS Lambda Rust Runtime&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;It walks through creating the new project, adding crates, and how to cross compile for Amazon Linux 2 on x86. Finally, create a new AWS lambda function and invoke using the cli.&lt;/p&gt;

&lt;p&gt;It was fun to get this started and there are a lot of additional things I can add around testing, logging.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>serverless</category>
      <category>aws</category>
    </item>
  </channel>
</rss>
