Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SLS-2330] Add support for universal instrumentation with the extension #116

Merged
merged 12 commits into from
Oct 28, 2022

Conversation

DylanLovesCoffee
Copy link
Contributor

@DylanLovesCoffee DylanLovesCoffee commented Oct 6, 2022

What does this PR do?

Extends the DD extension functionality in the Go Lambda library to support universal instrumentation. In short, this means that the extension will handle certain features such as adding function triggers, Lambda request and response to the span metadata and inferred spans.

Gated behind the DD_UNIVERSAL_INSTRUMENTATION env var.

Image 2022-10-06 at 11 23 45 AM

Motivation

Expand universal instrumentation to all runtimes.

Testing Guidelines

Manually with dev builds of the library

Additional Notes

Types of changes

  • Bug fix
  • New feature
  • Breaking change
  • Misc (docs, refactoring, dependency upgrade, etc.)

Checklist

  • This PR's description is comprehensive
  • This PR contains breaking changes that are documented in the description
  • This PR introduces new APIs or parameters that are documented and unlikely to change in the foreseeable future
  • This PR impacts documentation, and it has been updated (or a ticket has been logged)
  • This PR's changes are covered by the automated tests
  • This PR collects user input/sensitive content into Datadog

@codecov-commenter
Copy link

codecov-commenter commented Oct 6, 2022

Codecov Report

Merging #116 (73a5325) into main (bf8b37f) will decrease coverage by 1.06%.
The diff coverage is 68.29%.

@@            Coverage Diff             @@
##             main     #116      +/-   ##
==========================================
- Coverage   84.51%   83.45%   -1.07%     
==========================================
  Files          13       13              
  Lines         788      846      +58     
==========================================
+ Hits          666      706      +40     
- Misses         96      111      +15     
- Partials       26       29       +3     
Impacted Files Coverage Δ
internal/trace/listener.go 54.92% <31.25%> (-3.14%) ⬇️
internal/extension/extension.go 80.26% <72.72%> (-10.65%) ⬇️
ddlambda.go 79.61% <100.00%> (+1.04%) ⬆️
internal/wrapper/wrap_handler.go 97.93% <100.00%> (+0.02%) ⬆️

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@DylanLovesCoffee DylanLovesCoffee marked this pull request as ready for review October 7, 2022 20:58
@DylanLovesCoffee DylanLovesCoffee requested a review from a team as a code owner October 7, 2022 20:58
Copy link
Contributor

@purple4reina purple4reina left a comment

Choose a reason for hiding this comment

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

I made a few nit-picky suggestions. Feel free to take um or leave um.

ddlambda.go Show resolved Hide resolved
if response, err := em.httpClient.Do(req); err == nil && response.StatusCode == 200 {
// Propagate dd-trace context from the extension response if found in the response headers
traceId := response.Header.Values(string(DdTraceId))
if len(traceId) > 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if len(traceId) > 0 {
if traceId != "" {

Nit pick. In case you decide to use response.Header.Get, this is more performant.

Copy link
Contributor

Choose a reason for hiding this comment

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

For the record, I actually looked this up. It turns out that go compiles these two options to the same byte code. So, my recommendation here was in fact incorrect.

myStr := "hello world!"
// this line
if len(myStr) > 0 {
    ...
}
// compiles to the same byte code as this line
if myStr != "" {
    ...
}

internal/extension/extension.go Outdated Show resolved Hide resolved
internal/extension/extension.go Outdated Show resolved Hide resolved
internal/extension/extension.go Outdated Show resolved Hide resolved
internal/extension/extension.go Outdated Show resolved Hide resolved
internal/extension/extension.go Outdated Show resolved Hide resolved
internal/extension/extension.go Outdated Show resolved Hide resolved
internal/trace/listener_test.go Show resolved Hide resolved
em.isExtensionRunning = true
} else {
logger.Debug("Will use the API since the Serverless Agent was detected but the hello route was unreachable")
em.isExtensionRunning = false
Copy link
Contributor

Choose a reason for hiding this comment

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

I am wondering if you think we should still make this call to /hello in the case where universal instrumentation is not enabled?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Aha yup, good catch. I made a note to add this back but totally forgot 👍 side note: /hello is a confusing route name for its actual usage in the extension 😢

endInvocationUrl string
httpClient HTTPClient
isExtensionRunning bool
isUniversalInstrumentation bool
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looked into adding trace.Config + metrics.Config to this, but it was throwing errors for a circular dependency.

req, _ := http.NewRequest(http.MethodGet, em.helloRoute, nil)
if response, err := em.httpClient.Do(req); err == nil && response.StatusCode == 200 {
logger.Debug("Hit the extension /hello route")
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Previously, if there was an error hitting the hello route, we'd set em.isExtensionRunning = false and log.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Woops, adding that back in!

Copy link
Contributor

@purple4reina purple4reina left a comment

Choose a reason for hiding this comment

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

Loooks awesome 🎉

@Julio-Guerra
Copy link

Hello,
What's the plan regarding the DD_UNIVERSAL_INSTRUMENTATION env var? When do you think this is going to be enabled by default?

@DylanLovesCoffee
Copy link
Contributor Author

Hello, What's the plan regarding the DD_UNIVERSAL_INSTRUMENTATION env var? When do you think this is going to be enabled by default?

👋 Ideally we'll drop the environment variable in the future and have this enabled by default, matching the behavior for our other runtimes

@DylanLovesCoffee DylanLovesCoffee merged commit 1cdcde5 into main Oct 28, 2022
@DylanLovesCoffee DylanLovesCoffee deleted the dylan/universal-go branch October 28, 2022 17:15
@xrn
Copy link
Contributor

xrn commented Dec 28, 2022

@DylanLovesCoffee or @purple4reina are you able to help me understand what universal instrumentation is? I can not find any materials about it?

Also will universal_instrumentation: true work with datadog.yaml for lambda?

@DylanLovesCoffee
Copy link
Contributor Author

@xrn universal_instrumentation: true will not work with a datadog.yaml right now. The plan is to remove this flag in the near future. I will update the docs to give a mention to what this feature is: https://github.com/DataDog/documentation/pull/16214/files#diff-dec86e3385da3fbf860403d3a6225838f9aea041fc7ffe4bead805e2451719ffR71

peterdeme pushed a commit to spacelift-io/datadog-lambda-go that referenced this pull request Nov 15, 2023
peterdeme added a commit to spacelift-io/datadog-lambda-go that referenced this pull request Dec 4, 2023
* Create codeql-analysis.yml (DataDog#100)

* Create codeql-analysis.yml

* Update codeql-analysis.yml

* Update run_integration_tests.sh

* Do not show error messages even if neither DD_API_KEY nor DD_KMS_API_KEY is set when Lambda Extension is running (DataDog#102)

* Bump version to 1.4.0

* Bump go + fasthttp + lint (DataDog#104)

* Consolidate serverless configurations into one place (DataDog#105)

* Update README.md

* Update README.md

* Bump dd-trace-go to latest version to address some vulnerabilities (DataDog#109)

* Bump dd-trace-go to latest version to address some vulnaribilities
* update go.sum with `go mod tidy`

* Bump version to 1.6.0

* bump codeql (DataDog#112)

* Bump dd-trace-go to v1.41 (DataDog#115)

* Bump version to 1.7.0

* [SLS-2330] Add support for universal instrumentation with the extension (DataDog#116)

add option to use universal instrumentation

* [EEP-444] include error in failed metric send log (DataDog#118)

Co-authored-by: Corey Griffin <CoreyGriffin@users.noreply.github.com>

* [SLS-2492] Upgrade aws sdk v2 (DataDog#113)

upgrade sdk

* Bump version to 1.8.0

* Use new account in integration tests (DataDog#119)

* set the architecture explicitely (DataDog#122)

* mask init runtime logs (DataDog#123)

* Update libs (DataDog#121)

* bump go 1.18 (DataDog#125)

* Retry sending trace payloads on failure. (DataDog#128)

* Bump version to 1.9.0

* Update DD Trace to  v1.51.0(DataDog#133)

* Bump go version to 1.20 (DataDog#140)

Bump go version to 1.20

* Upgrade version of dd-trace-go to v1.54.1 (DataDog#141)

* Bump version to 1.10.0

* Propagate trace context from SQS events (DataDog#142)

* Default parent id to be trace id if not found elsewhere.

* Look for trace context in context object as well as headers.

* Apply trace context before starting the function execution span.

* Update signature in tests.

* Add spanid of execution span to context.

* Do not ignore priority "-128".

* Test that default parent id set to trace id.

* Test span id added to context.

* Test uses trace context from context object.

* Bump version to 1.11.0

* feat: automate AppSec enablement setup (e.g: `AWS_LAMBDA_RUNTIME_API`) (DataDog#143)

* feat: honor AWS_LAMBDA_EXEC_WRAPPER when AWS Lambda does not

In order to simplify onboarding & make it more uniform across languages,
inspect the value of the `AWS_LAMBDA_EXEC_WRAPPER` environment variable
and apply select environment variable changes it perofrms upon
decorating a handler.

This is necessary/useful because that environment variable is not
honored by custom runtimes (`provided`, `provided.al2`) as well as the
`go1.x` runtime (which is a glorified provided runtime). The datadog
Lambda wrapper starts a proxy to inject ASM functionality directly on
the Lambda runtime API instead of having to manually instrument each and
every lambda handler/application, and modifies `AWS_LAMBDA_RUNTIME_API`
to instruct Lambda language runtime client libraries to go through it
instead of directly interacting with the Lambda control plane.

APPSEC-11534

* pivot to a different, cheaper strategy

* typo fix

* PR feedback

* minor fixups

* add warning in go1.x runtime if lambda.norpc build tag was not enabled

* Bump version to 1.12.0

* Re-add configs after upstream rebase

* Bump packages

* Remove deprecated `io/ioutil` calls

---------

Co-authored-by: Tian Chu <tian.chu@datadoghq.com>
Co-authored-by: Soshi Katsuta <skatsuta@users.noreply.github.com>
Co-authored-by: Maxime David <maxime.david@datadoghq.com>
Co-authored-by: kimi <47579703+kimi-p@users.noreply.github.com>
Co-authored-by: Kimi Wu <kimi.wu@datadoghq.com>
Co-authored-by: Dylan Yang <dylan.yang@datadoghq.com>
Co-authored-by: Corey Griffin <15809365+CoreyGriffin@users.noreply.github.com>
Co-authored-by: Corey Griffin <CoreyGriffin@users.noreply.github.com>
Co-authored-by: Marcin Rabenda <xrn.design@gmail.com>
Co-authored-by: Rey Abolofia <purple4reina@gmail.com>
Co-authored-by: Rey Abolofia <rey.abolofia@datadoghq.com>
Co-authored-by: Andrew Rodriguez <49878080+zARODz11z@users.noreply.github.com>
Co-authored-by: Ivan Topolcic <IvanTopolcic@users.noreply.github.com>
Co-authored-by: Romain Marcadier <romain.muller@telecomnancy.net>
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.

None yet

5 participants