Skip to content

Add lambda-otel4s module#459

Open
alexcardell wants to merge 70 commits intotypelevel:mainfrom
alexcardell:lambda-otel4s
Open

Add lambda-otel4s module#459
alexcardell wants to merge 70 commits intotypelevel:mainfrom
alexcardell:lambda-otel4s

Conversation

@alexcardell
Copy link
Copy Markdown

@alexcardell alexcardell commented Feb 23, 2024

Supercedes #456

  • Adds lambda-natchez module
  • Adds lambda-otel4s module
    • Traces lambdas with semantic conventions applied
  • Adds otel4s examples
  • Add scalafix migration to port natchez package imports -- (removes previous version scalafix migrations)

This is targeting otel4s 0.16.x 0.15.x 0.14.x 0.13.x 0.12.x 0.11.x 0.10.x 0.9.x 0.8.x 0.7.x 0.6.x 0.5.x

Links

https://opentelemetry.io/docs/specs/semconv/faas/aws-lambda/
https://opentelemetry.io/docs/specs/semconv/faas/faas-spans/

@alexcardell
Copy link
Copy Markdown
Author

Currently pointed at a local snapshot so CI will definitely fail, as otel4s main has NoPublish for everything involving the SDK

@alexcardell alexcardell marked this pull request as ready for review March 12, 2024 19:21
@alexcardell alexcardell changed the title WIP: Add lambda-otel4s module Add lambda-otel4s module Mar 12, 2024
Comment thread lambda-otel4s/shared/src/main/scala/feral/lambda/otel4s/FaasAttributes.scala Outdated
Comment thread lambda-otel4s/shared/src/main/scala/feral/lambda/otel4s/TracedHandler.scala Outdated
Comment thread lambda-otel4s/shared/src/main/scala/feral/lambda/otel4s/package.scala Outdated
@alexcardell
Copy link
Copy Markdown
Author

@iRevive Updated all the attributes and removed semconv-experimental

Would appreciate another look when you have time

@iRevive
Copy link
Copy Markdown

iRevive commented Apr 20, 2024

@alexcardell the changes look good.

We still need to wait for a release of https://github.com/http4s/http4s-otel4s-middleware, right?

@alexcardell
Copy link
Copy Markdown
Author

The middleware would be useful for the example, but I don't believe it's necessary otherwise

@alexcardell alexcardell force-pushed the lambda-otel4s branch 2 times, most recently from 84ee6f9 to 96ce0a9 Compare May 8, 2024 09:39
@alexcardell
Copy link
Copy Markdown
Author

Upgraded to otel4s 0.7 but thanks to sbt 1.10 that required a few other updates

Also added http4s-otel4s-middleware to the example

Comment thread build.sbt Outdated
Comment on lines +201 to +203
.jvmSettings(libraryDependencies ++= Seq(
"org.typelevel" %%% "otel4s-oteljava-trace-testkit" % otel4sVersion % Test
))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use otel4s-sdk-trace-testkit to run tests across all platforms. Here is an example: alexcardell#2

@armanbilge
Copy link
Copy Markdown
Member

I'd like to merge this for an upcoming release! @alexcardell do you have more time to work on it? @iRevive any changes in otel4s since this PR was opened that we should account for? Thanks both for your work on this, sorry it took me so long to circle back 🙏

@iRevive
Copy link
Copy Markdown

iRevive commented Sep 13, 2024

@armanbilge I believe bumping otel4s version from 0.7.0 to 0.9.0 should be smooth.

One suggestion regarding this PR: we can switch to otel4s-sdk-trace-testkit to run tests across all platforms.

@alexcardell
Copy link
Copy Markdown
Author

@armanbilge I will fix it up!

@alexcardell
Copy link
Copy Markdown
Author

@iRevive thanks for the PR to my branch, sorry I did not notice that for many moons

@alexcardell
Copy link
Copy Markdown
Author

Added JS tests for the otel4s module -- they can't be in shared because of the different platform Contexts, without a fair bit of work

otel4s 0.8 looks like it works fine, however I can't update to 0.9 yet until http4s/http4s-otel4s-middleware#123 is in, as it's used in the examples module

@iRevive
Copy link
Copy Markdown

iRevive commented Sep 16, 2024

One more minor improvement: alexcardell#3.
We can use otel4s-semconv-experimental in tests to ensure our attributes match the specification.

/**
* Temporary aliases for Lambda message-specific attributes in otel4s-semconv-experimental
*/
object LambdaMessageAttributes {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should attributes be package private?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was a shim for otel4s-semconv-experimental anyway, back when I thought this would merge before that was available, I can probably replace this

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lambda-otel4s still cannot depend on the otel4s-semconv-experimental, because semconv-experimental may receive binary breaking updates. And this will affect feral compatibility.

So far, I came up with the following strategy:

  1. Redefine required attributes in the library (like you did), ideally in a private package
  2. Use otel4s-semconv-experimental in tests to ensure your attributes match the specification (even the experimental one).
  3. Once attributes get promoted to the otel4s-semconv stable artifact - replace handcrafted attributes with the stable one

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some specific attribute tests, a little bit boilerplatey but did catch a small issue

protected trait EventSpanAttributes[E] {
def contextCarrier(e: E): Map[String, String]
def spanKind: SpanKind
def attributes(e: E): List[Attribute[_]]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As an alternative, we can use Attributes collection there instead.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@iRevive
Copy link
Copy Markdown

iRevive commented Sep 16, 2024

I am not entirely clear how aws-otel Lambda layers will play with this, and whether that's in scope

This one is complicated. If I get it right, it's only a predefined (preinstalled) otel-compatible collector. Hence, it should work with otel4s-sdk and otel4s-oteljava out of the box.

Apart from the distro, there is a 'otel lambda layer': https://github.com/open-telemetry/opentelemetry-lambda.
Each language layer has a handcrafted entry point. The Java layer, for example, won't work with otel4-sdk but should work with otel4s-oteljava.

@alexcardell
Copy link
Copy Markdown
Author

Good to go when I can bump to otel4s 0.9, but given the middleware is only used in the examples, perhaps we can just indicate where you would wrap the client with the middleware, rather than adding that dependency

@iRevive
Copy link
Copy Markdown

iRevive commented Sep 16, 2024

There are also some AWS goodies in the upcoming 0.10.0 otel4s release (for otel4s-sdk): https://typelevel.org/otel4s/sdk/aws-xray-propagator.html#aws-lambda.

It depends on how urgently we need to release a new version of feral, but I'm fine with keeping examples out of the scope to unblock the release.

@armanbilge
Copy link
Copy Markdown
Member

It depends on how urgently we need to release a new version of feral

I don't have an urgency, I had neglected this PR so wanted to make sure that we can land it soon :) thanks both for refreshing things!

@alexcardell
Copy link
Copy Markdown
Author

Fixed the 0.9 issues, good to go

@alexcardell
Copy link
Copy Markdown
Author

bumped

apologies for the force push, rebasing was a pain


object TracedHandler {

def apply[F[_]: Monad: Tracer, Event, Result](
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should eventually add an overload that takes TracerProvider, e.g.:

def apply[F[_]: Monad: TracerProvider, Event, Result](...): F[Option[Result]] = 
  TracerProvider[F]
    .tracer("feral.lambda").withVersion(BuildInfo.version).get
    .flatMap { implicit T: Tracer[F] =>
      ... // rest of the code
    }

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am happy to swap it over if that's the preferred dependency, I think at the time I wrote this some libraries were accepting Tracer

I know we have some apps that set both up implicitly for that reason, and an overload may cause a problem unless specifically named

@iRevive
Copy link
Copy Markdown

iRevive commented Apr 15, 2026

@armanbilge looks good to me, would you mind taking a look too?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants