diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index b85263253..39dcb9047 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -121,3 +121,10 @@ jobs: name: LICENSE-3rdparty.yml path: /tmp/CI.yaml overwrite: true + verify-json-schema: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: DeterminateSystems/nix-installer-action@v13 + - uses: DeterminateSystems/magic-nix-cache-action@v7 + - run: rfc/0001-crashtracker-user-visable-log/verify_examples.sh \ No newline at end of file diff --git a/rfc/0001-crashtracker-user-visable-log/schema.json b/rfc/0001-crashtracker-user-visable-log/schema.json new file mode 100644 index 000000000..d1ae7386e --- /dev/null +++ b/rfc/0001-crashtracker-user-visable-log/schema.json @@ -0,0 +1,426 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "CrashInfo", + "type": "object", + "required": [ + "incomplete", + "os_info", + "uuid" + ], + "properties": { + "additional_stacktraces": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "$ref": "#/definitions/StackFrame" + } + } + }, + "counters": { + "type": "object", + "additionalProperties": { + "type": "integer", + "format": "int64" + } + }, + "files": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "incomplete": { + "type": "boolean" + }, + "metadata": { + "anyOf": [ + { + "$ref": "#/definitions/CrashtrackerMetadata" + }, + { + "type": "null" + } + ] + }, + "os_info": { + "$ref": "#/definitions/OsInfo" + }, + "proc_info": { + "anyOf": [ + { + "$ref": "#/definitions/ProcessInfo" + }, + { + "type": "null" + } + ] + }, + "siginfo": { + "anyOf": [ + { + "$ref": "#/definitions/SigInfo" + }, + { + "type": "null" + } + ] + }, + "span_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "uint128", + "minimum": 0.0 + } + }, + "stacktrace": { + "type": "array", + "items": { + "$ref": "#/definitions/StackFrame" + } + }, + "tags": { + "description": "Any additional data goes here", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "timestamp": { + "type": [ + "string", + "null" + ] + }, + "trace_ids": { + "type": "array", + "items": { + "type": "integer", + "format": "uint128", + "minimum": 0.0 + } + }, + "uuid": { + "type": "string" + } + }, + "definitions": { + "CrashtrackerMetadata": { + "type": "object", + "required": [ + "family", + "profiling_library_name", + "profiling_library_version", + "tags" + ], + "properties": { + "family": { + "type": "string" + }, + "profiling_library_name": { + "type": "string" + }, + "profiling_library_version": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "NormalizedAddress": { + "type": "object", + "required": [ + "file_offset", + "meta" + ], + "properties": { + "file_offset": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "meta": { + "$ref": "#/definitions/NormalizedAddressMeta" + } + } + }, + "NormalizedAddressMeta": { + "oneOf": [ + { + "type": "string", + "enum": [ + "Unknown" + ] + }, + { + "type": "object", + "required": [ + "Apk" + ], + "properties": { + "Apk": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "Elf" + ], + "properties": { + "Elf": { + "type": "object", + "required": [ + "path" + ], + "properties": { + "build_id": { + "type": [ + "array", + "null" + ], + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + }, + "path": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "Unexpected" + ], + "properties": { + "Unexpected": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "OsInfo": { + "type": "object", + "required": [ + "architecture", + "bitness", + "os_type", + "version" + ], + "properties": { + "architecture": { + "type": "string" + }, + "bitness": { + "type": "string" + }, + "os_type": { + "type": "string" + }, + "version": { + "$ref": "#/definitions/Version" + } + } + }, + "ProcessInfo": { + "type": "object", + "required": [ + "pid" + ], + "properties": { + "pid": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + } + }, + "SigInfo": { + "type": "object", + "required": [ + "signum" + ], + "properties": { + "signame": { + "type": [ + "string", + "null" + ] + }, + "signum": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + }, + "StackFrame": { + "description": "All fields are hex encoded integers.", + "type": "object", + "properties": { + "ip": { + "type": [ + "string", + "null" + ] + }, + "module_base_address": { + "type": [ + "string", + "null" + ] + }, + "names": { + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/StackFrameNames" + } + }, + "normalized_ip": { + "anyOf": [ + { + "$ref": "#/definitions/NormalizedAddress" + }, + { + "type": "null" + } + ] + }, + "sp": { + "type": [ + "string", + "null" + ] + }, + "symbol_address": { + "type": [ + "string", + "null" + ] + } + } + }, + "StackFrameNames": { + "type": "object", + "properties": { + "colno": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "filename": { + "type": [ + "string", + "null" + ] + }, + "lineno": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "name": { + "type": [ + "string", + "null" + ] + } + } + }, + "Version": { + "oneOf": [ + { + "type": "string", + "enum": [ + "Unknown" + ] + }, + { + "type": "object", + "required": [ + "Semantic" + ], + "properties": { + "Semantic": { + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 3, + "minItems": 3 + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "Rolling" + ], + "properties": { + "Rolling": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "Custom" + ], + "properties": { + "Custom": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + } + } + } \ No newline at end of file diff --git a/rfc/0001-crashtracker-user-visable-log/valid-example-1.json b/rfc/0001-crashtracker-user-visable-log/valid-example-1.json new file mode 100644 index 000000000..c98295c4d --- /dev/null +++ b/rfc/0001-crashtracker-user-visable-log/valid-example-1.json @@ -0,0 +1,123 @@ +{ + "counters": { + "unwinding": 0, + "not_profiling": 0, + "serializing": 1, + "collecting_sample": 0 + }, + "incomplete": false, + "metadata": { + "profiling_library_name": "crashtracking-test", + "profiling_library_version": "12.34.56", + "family": "crashtracking-test", + "tags": [] + }, + "os_info": { + "os_type": "Macos", + "version": { + "Semantic": [ + 14, + 5, + 0 + ] + }, + "edition": null, + "codename": null, + "bitness": "X64", + "architecture": "arm64" + }, + "proc_info": { + "pid": 95565 + }, + "siginfo": { + "signum": 11, + "signame": "SIGSEGV" + }, + "span_ids": [ + 42 + ], + "stackstrace": [ + { + "ip": "0x100f702ac", + "names": [ + { + "colno": 5, + "filename": + "/Users/daniel.schwartznarbonne/.cargo/registry/src/index.crates.io-6f17d22bba15001f/backtrace-0.3.71/src/backtrace/libunwind.rs", + "lineno": 105, + "name": "trace" + }, + { + "colno": 5, + "filename": + "/Users/daniel.schwartznarbonne/.cargo/registry/src/index.crates.io-6f17d22bba15001f/backtrace-0.3.71/src/backtrace/mod.rs", + "lineno": 66, + "name": + "trace_unsynchronized>" + }, + { + "colno": 5, + "filename": + "/Users/daniel.schwartznarbonne/go/src/github.com/DataDog/libdatadog/crashtracker/src/collectors.rs", + "lineno": 33, + "name": "emit_backtrace_by_frames" + } + ], + "sp": "0x16f9658c0", + "symbol_address": "0x100f702ac" + }, + { + "ip": "0x100f6f518", + "names": [ + { + "colno": 18, + "filename": + "/Users/daniel.schwartznarbonne/go/src/github.com/DataDog/libdatadog/crashtracker/src/crash_handler.rs", + "lineno": 379, + "name": "emit_crashreport" + }, + { + "colno": 23, + "filename": + "/Users/daniel.schwartznarbonne/go/src/github.com/DataDog/libdatadog/crashtracker/src/crash_handler.rs", + "lineno": 414, + "name": "handle_posix_signal_impl" + }, + { + "colno": 13, + "filename": + "/Users/daniel.schwartznarbonne/go/src/github.com/DataDog/libdatadog/crashtracker/src/crash_handler.rs", + "lineno": 264, + "name": "handle_posix_sigaction" + } + ], + "sp": "0x16f965940", + "symbol_address": "0x100f6f518" + }, + { + "ip": "0x186b9b584", + "names": [ + { + "name": "__simple_esappend" + } + ], + "sp": "0x16f965ae0", + "symbol_address": "0x186b9b584" + }, + { + "ip": "0x10049bd94", + "names": [ + { + "name": "_main" + } + ], + "sp": "0x16f965b10", + "symbol_address": "0x10049bd94" + } + ], + "trace_ids": [ + 18446744073709551617 + ], + "timestamp": "2024-07-19T16:52:16.422378Z", + "uuid": "a42add90-0e60-4799-b9f7-cbe0ebec4f27" + } \ No newline at end of file diff --git a/rfc/0001-crashtracker-user-visable-log/verify_examples.sh b/rfc/0001-crashtracker-user-visable-log/verify_examples.sh new file mode 100755 index 000000000..cc9469466 --- /dev/null +++ b/rfc/0001-crashtracker-user-visable-log/verify_examples.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env nix-shell +#!nix-shell -i bash -p yajsv + +# Copyright 2021-Present Datadog, Inc. https://www.datadoghq.com/ +# SPDX-License-Identifier: Apache-2.0' + +# this script uses nix provided yajsv to verify the examples using provided schema +# +# install nix locally to run this script (e.g. via https://github.com/DeterminateSystems/nix-installer) + +ROOT=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +cd ${ROOT} +yajsv -s schema.json "valid-*.json"