-
Notifications
You must be signed in to change notification settings - Fork 343
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[o11y] Support for Streaming Tail Worker outcome instrumentation for …
…most event types, initial testing
- Loading branch information
Showing
14 changed files
with
471 additions
and
107 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// Copyright (c) 2017-2023 Cloudflare, Inc. | ||
// Licensed under the Apache 2.0 license found in the LICENSE file or at: | ||
// https://opensource.org/licenses/Apache-2.0 | ||
export default { | ||
// https://developers.cloudflare.com/workers/observability/logs/tail-workers/ | ||
tail(...args) { | ||
return (...args) => {}; | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Copyright (c) 2017-2023 Cloudflare, Inc. | ||
// Licensed under the Apache 2.0 license found in the LICENSE file or at: | ||
// https://opensource.org/licenses/Apache-2.0 | ||
import * as assert from 'node:assert'; | ||
|
||
let resposeMap = new Map(); | ||
|
||
export default { | ||
// https://developers.cloudflare.com/workers/observability/logs/tail-workers/ | ||
tailStream(args) { | ||
// Invalid log statement, causes worker to not return a valid handler | ||
console.log(args.map((t) => t.logs)); | ||
return (args) => { | ||
console.log(args); | ||
}; | ||
}, | ||
}; | ||
|
||
export const test = { | ||
async test() { | ||
await scheduler.wait(100); | ||
// Tests for a bug where we tried to report an outcome event to a stream after setting up the | ||
// stream handler with the onset event failed – with an invalid tail handler, we should not | ||
// report any further events. | ||
// TODO: How to test this better? What we want to see here is there not being an | ||
// "Expected only a single onset event" error. | ||
assert.ok(resposeMap.size == 0); | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
using Workerd = import "/workerd/workerd.capnp"; | ||
|
||
const unitTests :Workerd.Config = ( | ||
services = [ | ||
( name = "http-test", | ||
worker = ( | ||
modules = [ | ||
( name = "worker", esModule = embed "http-test.js" ) | ||
], | ||
bindings = [ | ||
( name = "SERVICE", service = "http-test" ), | ||
( name = "CACHE_ENABLED", json = "false" ), | ||
], | ||
compatibilityDate = "2023-08-01", | ||
compatibilityFlags = ["nodejs_compat", "service_binding_extra_handlers", "cache_option_disabled"], | ||
tails = ["log"], | ||
), | ||
), | ||
# tail worker with tests | ||
( name = "log", | ||
worker = ( | ||
modules = [ | ||
(name = "worker", esModule = embed "tail-worker-test-invalid.js") | ||
], | ||
compatibilityDate = "2024-10-14", | ||
compatibilityFlags = ["experimental", "nodejs_compat"], | ||
), | ||
), | ||
], | ||
autogates = [ | ||
"workerd-autogate-streaming-tail-workers", | ||
], | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// Copyright (c) 2017-2023 Cloudflare, Inc. | ||
// Licensed under the Apache 2.0 license found in the LICENSE file or at: | ||
// https://opensource.org/licenses/Apache-2.0 | ||
import * as assert from 'node:assert'; | ||
|
||
let resposeMap = new Map(); | ||
|
||
export default { | ||
// https://developers.cloudflare.com/workers/observability/logs/tail-workers/ | ||
tailStream(...args) { | ||
// Onset event, must be singleton | ||
resposeMap.set(args[0].traceId, JSON.stringify(args[0].event)); | ||
return (...args) => { | ||
let cons = resposeMap.get(args[0].traceId); | ||
resposeMap.set(args[0].traceId, cons + JSON.stringify(args[0].event)); | ||
}; | ||
}, | ||
}; | ||
|
||
export const test = { | ||
async test() { | ||
// HACK: The prior tests terminates once the scheduled() invocation has returned a response, but | ||
// propagating the outcome of the invocation may take longer. Wait briefly so this can go ahead. | ||
await scheduler.wait(100); | ||
|
||
// The shared tail worker we configured only produces onset and outcome events, so every trace is identical here. | ||
// Number of traces based on how often main tail worker is invoked from previous tests | ||
let numTraces = 21; | ||
let basicTrace = | ||
'{"type":"onset","info":{"type":"trace","traces":[]}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}'; | ||
assert.deepStrictEqual( | ||
Array.from(resposeMap.values()), | ||
Array(numTraces).fill(basicTrace) | ||
); | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// Copyright (c) 2017-2023 Cloudflare, Inc. | ||
// Licensed under the Apache 2.0 license found in the LICENSE file or at: | ||
// https://opensource.org/licenses/Apache-2.0 | ||
import * as assert from 'node:assert'; | ||
|
||
let resposeMap = new Map(); | ||
|
||
export default { | ||
// https://developers.cloudflare.com/workers/observability/logs/tail-workers/ | ||
tailStream(...args) { | ||
// Onset event, must be singleton | ||
resposeMap.set(args[0].traceId, JSON.stringify(args[0].event)); | ||
return (...args) => { | ||
// TODO(streaming-tail-worker): Support several queued elements | ||
let cons = resposeMap.get(args[0].traceId); | ||
resposeMap.set(args[0].traceId, cons + JSON.stringify(args[0].event)); | ||
}; | ||
}, | ||
}; | ||
|
||
export const test = { | ||
async test() { | ||
// HACK: The prior tests terminates once the scheduled() invocation has returned a response, but | ||
// propagating the outcome of the invocation may take longer. Wait briefly so this can go ahead. | ||
await scheduler.wait(100); | ||
// This test verifies that we're able to receive tail stream events for various handlers. | ||
|
||
// Recorded streaming tail worker events, in insertion order. | ||
let response = Array.from(resposeMap.values()); | ||
|
||
let expected = [ | ||
// http-test.js: fetch and scheduled events get reported correctly. | ||
'{"type":"onset","info":{"type":"fetch","method":"POST","url":"http://placeholder/body-length","cfJson":"{}","headers":[]}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}', | ||
'{"type":"onset","info":{"type":"fetch","method":"POST","url":"http://placeholder/body-length","cfJson":"{}","headers":[]}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}', | ||
'{"type":"onset","info":{"type":"scheduled","scheduledTime":"1970-01-01T00:00:00.000Z","cron":""}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}', | ||
'{"type":"onset","info":{"type":"scheduled","scheduledTime":"1970-01-01T00:00:00.000Z","cron":"* * * * 30"}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}', | ||
'{"type":"onset","info":{"type":"fetch","method":"GET","url":"http://placeholder/not-found","cfJson":"{}","headers":[]}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}', | ||
'{"type":"onset","info":{"type":"fetch","method":"GET","url":"http://placeholder/web-socket","cfJson":"{}","headers":[]}}{"type":"outcome","outcome":"exception","cpuTime":0,"wallTime":0}', | ||
|
||
// queue-test.js: queue events | ||
'{"type":"onset","info":{"type":"fetch","method":"POST","url":"https://fake-host/message","cfJson":"{}","headers":[]}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}', | ||
'{"type":"onset","info":{"type":"fetch","method":"POST","url":"https://fake-host/message","cfJson":"{}","headers":[]}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}', | ||
'{"type":"onset","info":{"type":"fetch","method":"POST","url":"https://fake-host/message","cfJson":"{}","headers":[]}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}', | ||
'{"type":"onset","info":{"type":"fetch","method":"POST","url":"https://fake-host/message","cfJson":"{}","headers":[]}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}', | ||
'{"type":"onset","info":{"type":"fetch","method":"POST","url":"https://fake-host/batch","cfJson":"{}","headers":[]}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}', | ||
'{"type":"onset","info":{"type":"queue","queueName":"test-queue","batchSize":5}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}', | ||
|
||
// actor-alarms-test.js: alarm events | ||
'{"type":"onset","info":{"type":"fetch","method":"GET","url":"http://foo/test","cfJson":"{}","headers":[]}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}', | ||
'{"type":"onset","info":{"type":"alarm","scheduledTime":"1970-01-01T00:00:00.000Z"}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}', | ||
|
||
// legacy tail worker, triggered via alarm test. It would appear that these being recorded | ||
// after the onsets above is not guaranteed, but since the streaming tail worker is invoked | ||
// when the main invocation starts whereas the legacy tail worker is only invoked when it ends | ||
// this should be fine in practice. | ||
'{"type":"onset","info":{"type":"trace","traces":[""]}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}', | ||
'{"type":"onset","info":{"type":"trace","traces":[""]}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}', | ||
'{"type":"onset","info":{"type":"trace","traces":[""]}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}', | ||
|
||
// tests/websocket-hibernation.js: hibernatableWebSocket events | ||
'{"type":"onset","info":{"type":"fetch","method":"GET","url":"http://example.com/","cfJson":"{}","headers":[]}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}', | ||
'{"type":"onset","info":{"type":"fetch","method":"GET","url":"http://example.com/hibernation","cfJson":"{}","headers":[]}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}', | ||
'{"type":"onset","info":{"type":"hibernatableWebSocket","info":{"type":"message"}}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}', | ||
'{"type":"onset","info":{"type":"hibernatableWebSocket","info":{"type":"close","code":1000,"wasClean":true}}}{"type":"outcome","outcome":"ok","cpuTime":0,"wallTime":0}', | ||
]; | ||
|
||
assert.deepStrictEqual(response, expected); | ||
}, | ||
}; |
Oops, something went wrong.