8000 Implement dogstatsd, add timestamp support, fix flushing by nhulston · Pull Request #648 · DataDog/datadog-lambda-js · GitHub
[go: up one dir, main page]

Skip to content

Implement dogstatsd, add timestamp support, fix flushing #648

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

Merged
merged 22 commits into from
May 8, 2025

Conversation

nhulston
Copy link
Contributor
@nhulston nhulston commented May 7, 2025

What does this PR do?

  • Removes hot-shots
  • Implements dogstatsd ourselves
  • Updates dogstatsd implementation to support timestamps
  • Therefore, if the user has extension enabled and sends a metric with a timestamp, we can now use dogstatsd instead of directly using the API
  • This PR also implements a working flush. The previous implementation just closed the UDP socket on "flush" which actually just drops any unsent UDP packets, leading to lost metrics.
  • Just use one socket, no need to keep opening/closing sockets on every invocation

Motivation

  • hot-shots did not support metrics with timestamps, so originally we just sent metrics directly using the Datadog API
  • However, the DD API is not FIPs compliant. This seemed like the easiest solution
  • dogstatsd is a very simple protocol so might as well do it ourselves. Now, our performance should be slightly faster and our package size should be slightly smaller!

Testing Guidelines

  • Tested manually with a Lambda, calling sendDistributionMetric and sendDistributionMetricWithDate. Both work!
  • Unit tests

Additional Notes

  • This should be non-breaking, but this is a big change, so we should be careful and test a lot with self-monitoring before the next release.
  • Will deal with FIPs compliance stuff in a separate PR after this

Types of Changes

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

Check all that apply

  • 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
  • This PR passes the integration tests (ask a Datadog member to run the tests)

https://datadoghq.atlassian.net/browse/SVLS-6785

@nhulston nhulston force-pushed the nicholas.hulston/implement-dogstatsd branch from ac7357b to e1a206b Compare May 7, 2025 16:57
@nhulston nhulston changed the title [draft] Nicholas.hulston/implement dogstatsd Implement dogstatsd, support dogstatsd with timestamps, fix flushing May 7, 2025
@nhulston nhulston changed the title Implement dogstatsd, support dogstatsd with timestamps, fix flushing Implement dogstatsd, add timestamp support, fix flushing May 7, 2025
@nhulston nhulston force-pushed the nicholas.hulston/implement-dogstatsd branch from 9708108 to 48eb47d Compare May 7, 2025 19:00
@nhulston nhulston marked this pull request as ready for review May 7, 2025 19:17
@nhulston nhulston requested a review from a team as a code owner May 7, 2025 19:17
import { logDebug } from "../utils";

export class LambdaDogStatsD {
private static readonly HOST = "localhost";
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we set this to 127.0.0.1 instead of localhost, for safety

return;
}
const serializedTags = tags && tags.length ? `|#${this.normalizeTags(tags).join(",")}` : "";
const timeStampPart = timestamp != null ? `|T${timestamp}` : "";
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
const timeStampPart = timestamp != null ? `|T${timestamp}` : "";
const timestampPart = timestamp != null ? `|T${timestamp}` : "";

return;
}

const secondsSinceEpoch = Math.floor(metricTime.getTime() / 1000);
this.statsDClient?.distribution(name, value, secondsSinceEpoch, tags);
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
this.statsDClient?.distribution(name, value, secondsSinceEpoch, tags);
this.statsDClient.distribution(name, value, secondsSinceEpoch, tags);

Copy link
Contributor
@duncanista duncanista left a comment

Choose a reason for hiding this comment

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

Left some comments – would like to see if we can do millisecond/nanosecond resolution in Extension/Forwarder, just a nit

@nhulston
Copy link
Contributor Author
nhulston commented May 8, 2025

Left some comments – would like to see if we can do millisecond/nanosecond resolution in Extension/Forwarder, just a nit

We discussed in Slack but replying here for visibility:

  • The extension rounds metrics to the nearest 10 second bucket, so rounding here is fine
  • Also, timestamps with decimals are currently broken (this is a regression), but I opened a fix here: Fix parsing metrics with decimal timestamp serverless-components#17
  • In case customers in the future use old versions of the extension and new versions of datadog-lambda-js, I will make sure to round here for backwards compatibility

@nhulston nhulston requested a review from duncanista May 8, 2025 15:21
logDebug(`Socket send buffer increased to ${LambdaDogStatsD.MIN_SEND_BUFFER_SIZE / 1024}kb`);
}
} catch {
// ignore
Copy link
Contributor

Choose a reason for hiding this comment

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

why?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a debug log

@@ -509,7 +509,7 @@ describe("datadog", () => {

expect(mockedIncrementInvocations).toBeCalledTimes(1);
expect(mockedIncrementInvocations).toBeCalledWith(expect.anything(), mockContext);
expect(logger.debug).toHaveBeenCalledTimes(8);
expect(logger.debug).toHaveBeenCalledTimes(9);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

we get another debug log for increasing buffer send size

@nhulston nhulston force-pushed the nicholas.hulston/implement-dogstatsd branch from 537d86d to b7967e6 Compare May 8, 2025 19:36
@nhulston nhulston merged commit 45d33ad into main May 8, 2025
25 checks passed
@nhulston nhulston deleted the nicholas.hulston/implement-dogstatsd branch May 8, 2025 19:46
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.

2 participants
0