diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 7788847..119d50b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -79,8 +79,8 @@ jobs: # TODO: This needs to be updated once wasi-otel is merged into big Spin. - name: Setup Spin run: | - curl -LO https://github.com/asteurer/spin/releases/download/v0.1.0-otel/spin-linux-amd64 - echo "9b2bbcc98ddf2faeb31a8feda3672df0562052150abc96acf5351cc7d3b51f9a spin-linux-amd64" | sha256sum --check + curl -LO https://github.com/asteurer/spin/releases/download/v0.2.0-otel/spin-linux-amd64 + echo "94e31a56502026f83c12a843cf4aa7f3b5bf1d5a97fd18348fe78ab7f2ba4548 spin-linux-amd64" | sha256sum --check chmod +x spin-linux-amd64 mkdir -p $HOME/.local/bin mv spin-linux-amd64 $HOME/.local/bin/spin diff --git a/rust/src/logs/conversion.rs b/rust/src/logs/conversion.rs index 399991c..207cc03 100644 --- a/rust/src/logs/conversion.rs +++ b/rust/src/logs/conversion.rs @@ -61,7 +61,8 @@ impl<'a> Serialize for AnyValueWrapper<'a> { opentelemetry::logs::AnyValue::Bytes(bytes) => { // This is a workaround for JSON not having a way to differentiate between an array of bytes and an array of integers. let encoded = base64::engine::general_purpose::STANDARD.encode(bytes.as_ref()); - serializer.serialize_str(&format!("{{base64}}:{}", encoded)) + serializer + .serialize_str(&format!("data:application/octet-stream;base64,{}", encoded)) } opentelemetry::logs::AnyValue::ListAny(list) => { serialize_seq!(list, serializer, |v| &AnyValueWrapper(v)) @@ -129,7 +130,7 @@ mod tests { "key2": 123.456, "key3": 41, //'Hello, world!' encoded to base64 - "key4": "{base64}:SGVsbG8sIHdvcmxkIQ==", + "key4": "data:application/octet-stream;base64,SGVsbG8sIHdvcmxkIQ==", "key5": "This is a string", "key6": [1, 2, 3], "key7": { diff --git a/ts/src/logs.test.ts b/ts/src/logs.test.ts index 6e4f883..8a77a7f 100644 --- a/ts/src/logs.test.ts +++ b/ts/src/logs.test.ts @@ -29,7 +29,7 @@ describe('logAnyValueToWasi', () => { key2: 123.456, key3: 41, // 'Hello, world!' encoded to base64 - key4: '{base64}:SGVsbG8sIHdvcmxkIQ==', + key4: 'data:application/octet-stream;base64,SGVsbG8sIHdvcmxkIQ==', key5: 'This is a string', key6: [1, 2, 3], key7: { diff --git a/ts/src/logs.ts b/ts/src/logs.ts index c1b16b7..ee8b52a 100644 --- a/ts/src/logs.ts +++ b/ts/src/logs.ts @@ -57,7 +57,10 @@ function logAttributesToWasi(attrs: AnyValueMap): WasiKeyValue[] { export function logAnyValueToWasi(v: AnyValue): string { if (v instanceof Uint8Array) { - return JSON.stringify('{base64}:' + Buffer.from(v).toString('base64')); + return JSON.stringify( + 'data:application/octet-stream;base64,' + + Buffer.from(v).toString('base64') + ); } else if (v === null || v === undefined) { return 'null'; } else if (typeof v === 'string') { diff --git a/ts/types/interfaces/wasi-otel-types.d.ts b/ts/types/interfaces/wasi-otel-types.d.ts index 8987e6b..70e7b65 100644 --- a/ts/types/interfaces/wasi-otel-types.d.ts +++ b/ts/types/interfaces/wasi-otel-types.d.ts @@ -8,6 +8,10 @@ declare module 'wasi:otel/types@0.2.0-draft' { * * This corresponds with the `AnyValue` type defined in the [attribute spec](https://opentelemetry.io/docs/specs/otel/common/#anyvalue). * Because WIT doesn't support recursive types, the data needs to be serialized. JSON is used as the encoding format. + * + * Byte arrays require special encoding since JSON cannot distinguish them from number arrays. + * They are base64-encoded with a prefix that follows the Data URI RFC 2397 convention: + * `data:application/octet-stream;base64,` */ export type Value = string; /** diff --git a/ts/wit/types.wit b/ts/wit/types.wit index 6f8ce21..6fa87b5 100644 --- a/ts/wit/types.wit +++ b/ts/wit/types.wit @@ -14,6 +14,10 @@ interface types { /// /// This corresponds with the `AnyValue` type defined in the [attribute spec](https://opentelemetry.io/docs/specs/otel/common/#anyvalue). /// Because WIT doesn't support recursive types, the data needs to be serialized. JSON is used as the encoding format. + /// + /// Byte arrays require special encoding since JSON cannot distinguish them from number arrays. + /// They are base64-encoded with a prefix that follows the Data URI RFC 2397 convention: + /// `data:application/octet-stream;base64,` type value = string; /// An immutable representation of the entity producing telemetry as attributes. diff --git a/wit/types.wit b/wit/types.wit index 6f8ce21..6fa87b5 100644 --- a/wit/types.wit +++ b/wit/types.wit @@ -14,6 +14,10 @@ interface types { /// /// This corresponds with the `AnyValue` type defined in the [attribute spec](https://opentelemetry.io/docs/specs/otel/common/#anyvalue). /// Because WIT doesn't support recursive types, the data needs to be serialized. JSON is used as the encoding format. + /// + /// Byte arrays require special encoding since JSON cannot distinguish them from number arrays. + /// They are base64-encoded with a prefix that follows the Data URI RFC 2397 convention: + /// `data:application/octet-stream;base64,` type value = string; /// An immutable representation of the entity producing telemetry as attributes.