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

breaking: Use sha256 to hash lambda traceId that are triggered by Step Functions and set _dd.p.tid #534

Merged
merged 30 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
131f778
v1
kimi-p May 2, 2024
b9032cd
fix test
kimi-p May 2, 2024
aa1a0fa
remove md5 package and regenerate yarn lock
kimi-p May 2, 2024
60e0445
lint
kimi-p May 2, 2024
1617e1a
upgrade node/type
kimi-p May 7, 2024
858cfd5
fix 3 tests
kimi-p May 7, 2024
3338526
fix span ids for the same tests (previous commit was for trace id
kimi-p May 7, 2024
3c7b456
add @aws-crypto/sha256-js
kimi-p May 7, 2024
89a3ce3
remove 8h
kimi-p May 7, 2024
43fe7b8
Empty-Commit
kimi-p May 7, 2024
4ed002f
update yarn.lock
kimi-p May 7, 2024
1a22e0a
update 65th bit to be 0 and tests all accidentally pass
kimi-p May 16, 2024
ee7d6bd
rename
kimi-p May 16, 2024
eb49ebf
rename
kimi-p May 16, 2024
f3c87db
add option to hashing to 64 bits or 128 bits
kimi-p May 16, 2024
e8470cd
merge main
kimi-p May 16, 2024
d9c4072
update test name
kimi-p May 16, 2024
b3d76cd
try log-backend log
kimi-p May 22, 2024
36f3942
remote print
kimi-p May 22, 2024
a3b7bd7
update 64 zeros case
kimi-p May 22, 2024
e3be794
Empty-Commit
kimi-p May 22, 2024
848a3b2
Empty-Commit
kimi-p May 22, 2024
0de000f
lint
kimi-p May 22, 2024
0c3dbbd
Merge branch 'main' of github.com:DataDog/datadog-lambda-js into kimi…
kimi-p May 22, 2024
cf96c98
remove unnecessary edge case check
kimi-p May 31, 2024
8e28404
Merge branch 'main' into kimi/update-sha256
kimi-p Jun 4, 2024
0debb2a
small logic update from comment
kimi-p Jun 4, 2024
1837ffe
use .reduce()
kimi-p Jun 4, 2024
b385614
lazy load require dd-trace/packages/dd-trace/src/opentracing/span_con…
kimi-p Jun 4, 2024
d3e6fbf
lazy load tracer classes
duncanista Jun 5, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"@types/aws-sdk": "^2.7.0",
"@types/jest": "^26.0.23",
"@types/mock-fs": "4.13.0",
"@types/node": "^15.6.1",
"@types/node": "^20.12.10",
"@types/promise-retry": "^1.1.3",
"@types/shimmer": "^1.0.1",
"dd-trace": "^4.30.0",
Expand All @@ -38,12 +38,12 @@
"typescript": "^4.3.2"
},
"dependencies": {
"@aws-crypto/sha256-js": "5.2.0",
"dc-polyfill": "^0.1.3",
"hot-shots": "8.5.0",
"promise-retry": "^2.0.1",
"serialize-error": "^8.1.0",
"shimmer": "1.2.1",
"ts-md5": "1.3.1"
"shimmer": "1.2.1"
},
"jest": {
"verbose": true,
Expand Down
4 changes: 2 additions & 2 deletions src/trace/context/extractor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -688,8 +688,8 @@ describe("TraceContextExtractor", () => {
const traceContext = await extractor.extract(event, {} as Context);
expect(traceContext).not.toBeNull();

expect(traceContext?.toTraceId()).toBe("947965466153612645");
expect(traceContext?.toSpanId()).toBe("4602916161841036335");
expect(traceContext?.toTraceId()).toBe("3661440683");
expect(traceContext?.toSpanId()).toBe("2846425757");
expect(traceContext?.sampleMode()).toBe("1");
expect(traceContext?.source).toBe("event");
});
Expand Down
8 changes: 4 additions & 4 deletions src/trace/context/extractors/step-function.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ describe("StepFunctionEventTraceExtractor", () => {
const traceContext = extractor.extract(payload);
expect(traceContext).not.toBeNull();

expect(traceContext?.toTraceId()).toBe("947965466153612645");
expect(traceContext?.toSpanId()).toBe("4602916161841036335");
expect(traceContext?.toTraceId()).toBe("3661440683");
expect(traceContext?.toSpanId()).toBe("2846425757");
expect(traceContext?.sampleMode()).toBe("1");
expect(traceContext?.source).toBe("event");
});
Expand All @@ -49,8 +49,8 @@ describe("StepFunctionEventTraceExtractor", () => {
const traceContext = extractor.extract(payload);
expect(traceContext).not.toBeNull();

expect(traceContext?.toTraceId()).toBe("947965466153612645");
expect(traceContext?.toSpanId()).toBe("4602916161841036335");
expect(traceContext?.toTraceId()).toBe("3661440683");
expect(traceContext?.toSpanId()).toBe("2846425757");
expect(traceContext?.sampleMode()).toBe("1");
expect(traceContext?.source).toBe("event");
});
Expand Down
41 changes: 15 additions & 26 deletions src/trace/step-function-service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,8 @@ describe("StepFunctionContextService", () => {

expect(spanContext).not.toBeNull();

expect(spanContext?.toTraceId()).toBe("947965466153612645");
expect(spanContext?.toSpanId()).toBe("4602916161841036335");
expect(spanContext?.toTraceId()).toBe("3661440683");
expect(spanContext?.toSpanId()).toBe("2846425757");
expect(spanContext?.sampleMode()).toBe("1");
expect(spanContext?.source).toBe("event");
});
Expand All @@ -215,15 +215,15 @@ describe("StepFunctionContextService", () => {
it("returns the same hash number generated in `logs backend` for a random string", () => {
const instance = StepFunctionContextService.instance();
const hash = instance["deterministicMd5HashToBigIntString"]("some_testing_random_string");
expect(hash).toEqual("2251275791555400689");
expect(hash).toEqual("80506605202309154694697844088692857990");
});

it("returns the same hash number generated in `logs backend` for execution id # state name # entered time", () => {
const instance = StepFunctionContextService.instance();
const hash = instance["deterministicMd5HashToBigIntString"](
"arn:aws:states:sa-east-1:601427271234:express:DatadogStateMachine:acaf1a67-336a-e854-1599-2a627eb2dd8a:c8baf081-31f1-464d-971f-70cb17d01111#step-one#2022-12-08T21:08:19.224Z",
);
expect(hash).toEqual("8034507082463708833");
expect(hash).toEqual("80072419077927731656239868244106251139");
});
});

Expand All @@ -232,22 +232,22 @@ describe("StepFunctionContextService", () => {
[
"a random string",
"some_testing_random_string",
"0001111100111110001000110110011110010111000110001001001111110001",
"00111100100100010000001000010111010011000111001011011001111000000110011101111001100001011100111110110001011111001101110010000110",
],
[
"an execution id",
"arn:aws:states:sa-east-1:601427271234:express:DatadogStateMachine:acaf1a67-336a-e854-1599-2a627eb2dd8a:c8baf081-31f1-464d-971f-70cb17d041f4",
"0010010000101100100000101011111101111100110110001110111100111101",
"01000101001100100100101000010110011101001110110101001100100001000100010111011110010011011100010100101011110110011010110001111110",
],
[
"another execution id",
"arn:aws:states:sa-east-1:601427271234:express:DatadogStateMachine:acaf1a67-336a-e854-1599-2a627eb2dd8a:c8baf081-31f1-464d-971f-70cb17d01111",
"0010001100110000011011011111010000100111100000110000100100101010",
"00101111100011001000100001010011001100000000000101110111001010110100110111010111011001101001111001110001011111000111010010101001",
],
[
"execution id # state name # entered time",
"arn:aws:states:sa-east-1:601427271234:express:DatadogStateMachine:acaf1a67-336a-e854-1599-2a627eb2dd8a:c8baf081-31f1-464d-971f-70cb17d01111#step-one#2022-12-08T21:08:19.224Z",
"0110111110000000010011011001111101110011100111000000011010100001",
"00111100001111010110001100001111111100111110101100000000001000010011110011111110111010000100011111010100111110011000101110000011",
],
])("returns the same hash number generated in `logs backend` for %s", (_, str, expected) => {
const instance = StepFunctionContextService.instance();
Expand Down Expand Up @@ -276,27 +276,16 @@ describe("StepFunctionContextService", () => {
});
});

describe("hexToBinary", () => {
describe("numberToBinaryString", () => {
const instance = StepFunctionContextService.instance();
it.each([
["0", "0000"],
["1", "0001"],
["2", "0010"],
["3", "0011"],
["4", "0100"],
["5", "0101"],
["6", "0110"],
["7", "0111"],
["8", "1000"],
["9", "1001"],
["a", "1010"],
["b", "1011"],
["c", "1100"],
["d", "1101"],
["e", "1110"],
["f", "1111"],
[0, "00000000"],
[1, "00000001"],
[2, "00000010"],
[3, "00000011"],
[4, "00000100"],
])("returns the right binary number for %s => %s", (hex, expected) => {
const binary = instance["hexToBinary"](hex);
const binary = instance["numberToBinaryString"](hex);
expect(binary).toBe(expected);
});
});
Expand Down
26 changes: 13 additions & 13 deletions src/trace/step-function-service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Md5 } from "ts-md5";
import { logDebug } from "../utils";
import { SampleMode, TraceSource } from "./trace-context-service";
import { SpanContextWrapper } from "./span-context-wrapper";
import { Sha256 } from "@aws-crypto/sha256-js";

export interface StepFunctionContext {
"step_function.execution_name": string;
Expand Down Expand Up @@ -146,28 +146,28 @@ export class StepFunctionContextService {
}

private deterministicMd5HashToBigIntString(s: string): string {
const binaryString = this.deterministicMd5HashInBinary(s);
const binaryString = this.deterministicSha256Hash(s);
return BigInt("0b" + binaryString).toString();
}

private deterministicMd5HashInBinary(s: string): string {
// Md5 here is used here because we don't need a cryptographically secure hashing method but to generate the same trace/span ids as the backend does
const hex = Md5.hashStr(s);
private deterministicSha256Hash(s: string): string {
const hash = new Sha256();
hash.update(s);
const hex = hash.digestSync().subarray(0, 16);

let binary = "";
for (let i = 0; i < hex.length; i++) {
const ch = hex.charAt(i);
binary = binary + this.hexToBinary(ch);
let binaryString = "";
for (const num of hex) {
binaryString = binaryString + this.numberToBinaryString(num);
}

const res = "0" + binary.substring(1, 64);
if (res === "0".repeat(64)) {
const res = "0" + binaryString.substring(1, 64) + "0" + binaryString.substring(65, 128);
if (res === "0".repeat(128)) {

Choose a reason for hiding this comment

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

Here, we need to ensure that the 0th and 64th bits of the 128-bit data are both set to 0.

return "1";
}
return res;
}

private hexToBinary(hex: string) {
return parseInt(hex, 16).toString(2).padStart(4, "0");
private numberToBinaryString(num: number): string {
return num.toString(2).padStart(8, "0");
}
}
Loading