diff --git a/.github/workflows/haskell.yml b/.github/workflows/haskell.yml index a673ef02..71e52a71 100644 --- a/.github/workflows/haskell.yml +++ b/.github/workflows/haskell.yml @@ -2,45 +2,12 @@ on: push: pull_request: jobs: - stack-ghc-8_10: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: cachix/install-nix-action@v22 - with: - nix_path: nixpkgs=channel:nixos-22.11 - - uses: haskell-actions/setup@v2 - id: setup - with: - enable-stack: true - - if: ${{ runner.os == 'Linux' }} - # https://github.com/actions/runner-images/issues/7061 - run: sudo chown -R $USER /usr/local/.ghcup - - uses: actions/cache/restore@v4 - id: cache - env: - key: ${{ runner.os }}-ghc-8.10-stack-${{ steps.setup.outputs.stack-version }} - with: - path: | - ${{ steps.setup.outputs.stack-root }} - .stack-work - key: ${{ env.key }}-${{ hashFiles('stack-ghc-8.10.yaml.lock') }} - restore-keys: ${{ env.key }}- - - run: stack --stack-yaml stack-ghc-8.10.yaml build --test --no-run-tests --bench --no-run-benchmarks --only-dependencies - - uses: actions/cache/save@v4 - if: steps.cache.outputs.cache-hit != 'true' - with: - path: | - ${{ steps.setup.outputs.stack-root }} - .stack-work - key: ${{ steps.cache.outputs.cache-primary-key }} - - run: stack --stack-yaml stack-ghc-8.10.yaml build - - run: stack --stack-yaml stack-ghc-8.10.yaml test - - run: stack --stack-yaml stack-ghc-8.10.yaml bench --no-run-benchmarks stack-ghc-9_0: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + submodules: true - uses: cachix/install-nix-action@v22 with: nix_path: nixpkgs=channel:nixos-22.11 @@ -76,6 +43,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + submodules: true - uses: cachix/install-nix-action@v22 with: nix_path: nixpkgs=channel:nixos-22.11 @@ -111,6 +80,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + with: + submodules: true - uses: cachix/install-nix-action@v25 with: nix_path: nixpkgs=channel:nixos-22.11 diff --git a/.gitmodules b/.gitmodules index a564a498..bc5716e2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "proto"] path = proto url = https://github.com/open-telemetry/opentelemetry-proto +[submodule "semantic-conventions/model"] + path = semantic-conventions/model + url = https://github.com/open-telemetry/semantic-conventions/ diff --git a/Makefile b/Makefile index c37c2d08..0ecbd68d 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,5 @@ .PHONY: all -all: all.stack-8.10 all.stack-9.0 all.stack-9.2 all.cabal-9.0 - -.PHONY: all.stack-8.10 -all.stack-8.10: - stack --stack-yaml stack-ghc-8.10.yaml build --test --bench +all: all.stack-9.0 all.stack-9.2 all.cabal-9.0 .PHONY: all.stack-9.0 all.stack-9.0: @@ -19,11 +15,7 @@ all.cabal-9.0: cabal v2-test --jobs all .PHONY: build.all -build.all: build.all.stack-8.10 build.all.stack-9.0 build.all.stack-9.2 build.all.cabal-9.0 - -.PHONY: build.all.stack-8.10 -build.all.stack-8.10: - stack --stack-yaml stack-ghc-8.10.yaml build --test --no-run-tests --bench --no-run-benchmarks +build.all: build.all.stack-9.0 build.all.stack-9.2 build.all.cabal-9.0 .PHONY: build.all.stack-9.0 build.all.stack-9.0: diff --git a/api/src/OpenTelemetry/Attributes/Key.hs b/api/src/OpenTelemetry/Attributes/Key.hs index 8b90e882..6f2c7f25 100644 --- a/api/src/OpenTelemetry/Attributes/Key.hs +++ b/api/src/OpenTelemetry/Attributes/Key.hs @@ -13,275 +13,8 @@ Portability : non-portable (GHC extensions) module OpenTelemetry.Attributes.Key ( Key (..), forget, - - -- * Semantic conventions - -- $semanticConversions - - -- ** Attributes Registry - -- $attributesRegistry - - -- *** Cloud - -- $tbd - - -- *** Code - -- $code - code_column, - code_filepath, - code_function, - code_lineno, - code_namespace, - - -- *** Container - -- $container - container_command, - container_commandArgs, - container_commandLine, - container_id, - container_image_id, - container_image_name, - container_image_repoDigests, - container_image_tags, - container_name, - container_runtime, - - -- *** HTTP - -- $http - http_request_body_size, - http_request_header, - http_request_method, - http_request_methodOriginal, - http_request_resendCount, - http_response_body_size, - http_response_header, - http_response_statusCode, - http_route, - - -- *** Messaging - -- $tbd - - -- *** Network - -- $network - network_carrier_icc, - network_carrier_mcc, - network_carrier_mnc, - network_carrier_name, - network_connection_subtype, - network_connection_type, - network_local_address, - network_local_port, - network_peer_address, - network_peer_port, - network_protocol_name, - network_protocol_version, - network_transport, - network_type, - - -- *** Open Container Initiative - -- $tbd - - -- *** RPC - -- $rpc - rpc_connectRpc_errorCode, - rpc_connectRpc_request_metadata, - rpc_connectRpc_response_metadata, - rpc_grpc_request_metadata, - rpc_grpc_response_metadata, - rpc_grpc_statusCode, - rpc_jsonrpc_errorCode, - rpc_jsonrpc_errorMessage, - rpc_jsonrpc_requestId, - rpc_jsonrpc_version, - rpc_method, - rpc_service, - rpc_system, - - -- *** Thread - -- $tbd - - -- *** URL - -- $tbd - url_full, - - -- *** User agent - -- $tbd - - -- ** General Attributes - -- $generalAttributes - - -- *** Server, client and shared network attributes - -- $serverClientSharedNetworkAttributes - server_address, - server_port, - client_address, - client_port, - - -- *** Source and destination attributes - -- $sourceAndDestinationAttributes - source_address, - source_port, - destination_address, - destination_port, - - -- *** General remote service attributes - -- $generalRemoteServiceAttributes - peer_service, - - -- *** General identity attributes - -- $generalIdentityAttributes - enduser_id, - enduser_role, - enduser_scope, - - -- ** Event Attributes - -- $eventAttributes - - -- *** General event attributes - -- $generalEventAttributes - event_domain, - event_name, - - -- ** General Logs Attributes - -- $generalLogsAttributes - - -- *** General log identification attributes - -- $generalLogIdentificationAttributes - log_record_uid, - - -- *** Log media - -- $logMedia - log_file_name, - log_file_nameResolved, - log_file_path, - log_file_pathResolved, - log_iostream, - - -- ** Session - - -- *** Attributes - session_id, - session_previousId, - - -- ** Tracing Compatibility Components - - -- *** OpenTracing - opentracing_refType, - - -- ** Cloud Providers - - -- *** AWS SDK - -- $awsSdk - aws_requestId, - - -- ** CloudEvents - - -- *** CloudEvents Spans - -- $tbd - - -- ** Database Calls and Systems - - -- *** AWS DynamoDB - -- $tbd - - -- *** Cassandra - -- $tbd - - -- *** Database Client Calls - -- $databaseClientCalls - db_connectionString, - db_system, - db_user, - db_name, - db_operation, - db_statement, - - -- *** Microsoft Cosmos DB - -- $tbd - - -- *** CouchDB - -- $tbd - - -- *** Elasticsearch - -- $tbd - - -- *** GraphQL Server - -- $tbd - - -- *** HBase - -- $tbd - - -- *** Database Metrics - -- $tbd - - -- *** MongoDB - -- $tbd - - -- *** MSSQL - -- $tbd - - -- *** Redis - -- $redis - db_redis_databaseIndex, - - -- *** SQL Database - -- $sqlDatabase - db_sql_table, - - -- ** Exceptions - - -- *** Exceptions in logs - -- $tbd - - -- *** Exceptions in spans - -- $tbd - - -- ** Function-as-a-Service - -- $tbd - - -- ** Feature Flags - -- $tbd - - -- ** HTTP - - -- *** HTTP metrics - -- $httpMetrics - error_type, - - -- *** HTTP spans - -- $httpSpans - - -- ** Messaging Systems - -- $tbd - - -- ** Mobile Platform - -- $tbd - - -- ** Object Stores - -- $tbd - - -- ** Resource - -- $tbd - - -- *** Function as a Service - -- $faas - faas_instance, - faas_maxMemory, - faas_name, - faas_version, - - -- ** RPC - -- $tbd - - -- ** Runtime Environment - -- $tbd - - -- ** System - -- $tbd - - -- ** URL - -- $tbd ) where -import Data.Int (Int64) import Data.String (IsString (..)) import Data.Text (Text) import qualified Data.Text as T @@ -289,9 +22,6 @@ import GHC.Generics (Generic) import OpenTelemetry.Attributes.Attribute (Attribute) -{-# ANN module ("HLint: ignore Use camelCase" :: String) #-} - - newtype Key a = Key {unkey :: Text} deriving stock (Show, Eq, Ord, Generic) @@ -303,721 +33,3 @@ instance IsString (Key a) where forget :: Key a -> Key Attribute forget = Key . unkey - - -{- $semanticConversions - -An Attribute is a key-value pair, which MUST have the following properties: - - The attribute key MUST be a non-@null@ and non-empty string. - -- The attribute value is either: - - - A primitive type: string, boolean, double precision floating point (IEEE 754-1985) or signed 64 bit integer. - - An array of primitive type values. The array MUST be homogeneous, i.e., it MUST NOT contain values of different types. For protocols that do not natively support array values such values SHOULD be represented as JSON strings. - -Attribute values expressing a numerical value of zero, an empty string, or an empty array are considered meaningful and MUST be stored and passed on to processors \/ exporters. - -Specification: https://opentelemetry.io/docs/specs/otel/common/ --} - - -{- $attributesRegistry - -The attributes registry is the place where attributes are defined. - -Specification: https://opentelemetry.io/docs/specs/semconv/attributes-registry/ --} - - -{- $code -These attributes allow to report this unit of code and therefore to provide more context about the telemetry data. - -Specification: https://opentelemetry.io/docs/specs/semconv/attributes-registry/code/ --} - - -{- | The column number in @code.filepath@ best representing the operation. -It SHOULD point within the code unit named in @code.function@. --} -code_column :: Key Int64 -code_column = "code.column" - - --- | The source code file name that identifies the code unit as uniquely as possible (preferably an absolute file path). -code_filepath :: Key Text -code_filepath = "code.filepath" - - --- | The method or function name, or equivalent (usually rightmost part of the code unit's name). -code_function :: Key Text -code_function = "code.function" - - -{- | The line number in @code.filepath@ best representing the operation. -It SHOULD point within the code unit named in @code.function@. --} -code_lineno :: Key Int64 -code_lineno = "code.lineno" - - -{- | The “namespace” within which @code.function@ is defined. -Usually the qualified class or module name, such that @code.namespace@ + some separator + @code.function@ form a unique identifier for the code unit. --} -code_namespace :: Key Text -code_namespace = "code.namespace" - - -{- $container -Specification: https://opentelemetry.io/docs/specs/semconv/attributes-registry/container/ --} - - --- | The command used to run the container (i.e. the command name). -container_command :: Key Text -container_command = "container.command" - - --- | All the command arguments (including the command\/executable itself) run by the container. -container_commandArgs :: Key [Text] -container_commandArgs = "container.command_args" - - --- | The full command run by the container as a single string representing the full command. -container_commandLine :: Key Text -container_commandLine = "container.command_line" - - -{- | Container ID. Usually a UUID, as for example used to (identify Docker containers)[https://docs.docker.com/engine/reference/run/#container-identification]. -The UUID might be abbreviated. --} -container_id :: Key Text -container_id = "container.id" - - --- | Runtime specific image identifier. Usually a hash algorithm followed by a UUID. -container_image_id :: Key Text -container_image_id = "container.image.id" - - --- | Name of the image the container was built on. -container_image_name :: Key Text -container_image_name = "container.image.name" - - --- | Repo digests of the container image as provided by the container runtime. -container_image_repoDigests :: Key [Text] -container_image_repoDigests = "container.image.repo_digests" - - -{- | Container image tags. An example can be found in [Docker Image Inspect](https://docs.docker.com/engine/api/v1.43/#tag/Image/operation/ImageInspect). -Should be only the @@ section of the full name for example from @registry.example.com/my-org/my-image:@. --} -container_image_tags :: Key [Text] -container_image_tags = "container.image.tags" - - --- | Container name used by container runtime. -container_name :: Key Text -container_name = "container.name" - - --- | The container runtime managing this container. -container_runtime :: Key Text -container_runtime = "container.runtime" - - -{- $http -Specification: https://opentelemetry.io/docs/specs/semconv/attributes-registry/http/ --} - - --- | The size of the request payload body in bytes. -http_request_body_size :: Key Int64 -http_request_body_size = "http.request.body.size" - - --- | HTTP request headers, @key@ being the normalized HTTP Header name (lowercase), the value being the header values. -http_request_header :: Text -> Key [Text] -http_request_header key = Key $ "http.request.header." <> key - - --- | HTTP request method. -http_request_method :: Key Text -http_request_method = "http.request.method" - - --- | Original HTTP method sent by the client in the request line. -http_request_methodOriginal :: Key Text -http_request_methodOriginal = "http.request.method_original" - - --- | The ordinal number of request resending attempt (for any reason, including redirects). -http_request_resendCount :: Key Int64 -http_request_resendCount = "http.request.resend_count" - - --- | The size of the response payload body in bytes. -http_response_body_size :: Key Int64 -http_response_body_size = "http.response.body.size" - - --- | HTTP response headers, @key@ being the normalized HTTP Header name (lowercase), the value being the header values. -http_response_header :: Text -> Key [Text] -http_response_header key = Key $ "http.response.header." <> key - - --- | [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). -http_response_statusCode :: Key Int64 -http_response_statusCode = "http.response.status_code" - - --- | The matched route, that is, the path template in the format used by the respective server framework. -http_route :: Key Text -http_route = "http.route" - - --- | The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. -network_carrier_icc :: Key Text -network_carrier_icc = "network.carrier.icc" - - --- | The mobile carrier country code. -network_carrier_mcc :: Key Text -network_carrier_mcc = "network.carrier.mcc" - - --- | The mobile carrier network code. -network_carrier_mnc :: Key Text -network_carrier_mnc = "network.carrier.mnc" - - --- | The name of the mobile carrier. -network_carrier_name :: Key Text -network_carrier_name = "network.carrier.name" - - --- | This describes more details regarding the @network.connection.type@. -network_connection_subtype :: Key Text -network_connection_subtype = "network.connection.subtype" - - --- | The internet connection type. -network_connection_type :: Key Text -network_connection_type = "network.connection.type" - - --- | Local address of the network connection - IP address or Unix domain socket name. -network_local_address :: Key Text -network_local_address = "network.local.address" - - --- | Local port number of the network connection. -network_local_port :: Key Int64 -network_local_port = "network.local.port" - - --- | Peer address of the network connection - IP address or Unix domain socket name. -network_peer_address :: Key Text -network_peer_address = "network.peer.address" - - --- | Peer port number of the network connection. -network_peer_port :: Key Int64 -network_peer_port = "network.peer.port" - - --- | OSI application layer or non-OSI equivalent. -network_protocol_name :: Key Text -network_protocol_name = "network.protocol.name" - - --- | Version of the protocol specified in @network.protocol.name@. -network_protocol_version :: Key Text -network_protocol_version = "network.protocol.version" - - --- | OSI transport layer or inter-process communication method. -network_transport :: Key Text -network_transport = "network.transport" - - --- | OSI network layer or non-OSI equivalent. -network_type :: Key Text -network_type = "network.type" - - -{- $rpc -RPC attributes are intended to be used in the context of events related to remote procedure calls (RPC). - -Specification: https://opentelemetry.io/docs/specs/semconv/attributes-registry/rpc/ --} - - --- | The [error codes](https://connect.build/docs/protocol/#error-codes) of the Connect request. Error codes are always string values. -rpc_connectRpc_errorCode :: Key Text -rpc_connectRpc_errorCode = "rpc.connect_rpc.error_code" - - --- | Connect request metadata, @key@ being the normalized Connect Metadata key (lowercase), the value being the metadata values. -rpc_connectRpc_request_metadata :: Text -> Key [Text] -rpc_connectRpc_request_metadata key = Key $ "rpc.connect_rpc.request_metadata." <> key - - --- | Connect response metadata, @key@ being the normalized Connect Metadata key (lowercase), the value being the metadata values. -rpc_connectRpc_response_metadata :: Text -> Key [Text] -rpc_connectRpc_response_metadata key = Key $ "rpc.connect_rpc.response_metadata." <> key - - --- | gRPC request metadata, @key@ being the normalized gRPC Metadata key (lowercase), the value being the metadata values. -rpc_grpc_request_metadata :: Text -> Key [Text] -rpc_grpc_request_metadata key = Key $ "rpc.grpc.request_metadata." <> key - - --- | gRPC response metadata, @key@ being the normalized gRPC Metadata key (lowercase), the value being the metadata values. -rpc_grpc_response_metadata :: Text -> Key [Text] -rpc_grpc_response_metadata key = Key $ "rpc.grpc.response_metadata." <> key - - --- | The [numeric status code](https://github.com/grpc/grpc/blob/v1.33.2/doc/statuscodes.md) of the gRPC request. -rpc_grpc_statusCode :: Key Int64 -rpc_grpc_statusCode = "rpc.grpc.status_code" - - --- | @error.code@ property of response if it is an error response. -rpc_jsonrpc_errorCode :: Key Int64 -rpc_jsonrpc_errorCode = "rpc.jsonrpc.error_code" - - --- | @error.message@ property of response if it is an error response. -rpc_jsonrpc_errorMessage :: Key Text -rpc_jsonrpc_errorMessage = "rpc.jsonrpc.error_message" - - --- | @id@ property of request or response. Since protocol allows id to be int, string, null or missing (for notifications), value is expected to be cast to string for simplicity. Use empty string in case of null value. Omit entirely if this is a notification. -rpc_jsonrpc_requestId :: Key Text -rpc_jsonrpc_requestId = "rpc.jsonrpc.request_id" - - --- | Protocol version as in @jsonrpc@ property of request/response. Sinse JSON-RPC 1.0 does not specify this, the value can be omitted. -rpc_jsonrpc_version :: Key Text -rpc_jsonrpc_version = "rpc.jsonrpc.version" - - --- | The name of the (logical) method being called, must be equal to the $method part in the span name. -rpc_method :: Key Text -rpc_method = "rpc.method" - - --- | The full (logical) name of the service being called, including its package name, if applicable. -rpc_service :: Key Text -rpc_service = "rpc.service" - - --- | A string identifying the remoting system. See below for a list of well-known identifiers. -rpc_system :: Key Text -rpc_system = "rpc.system" - - --- | Absolute URL describing a network resource according to [RFC3986](https://www.rfc-editor.org/rfc/rfc3986). -url_full :: Key Text -url_full = "url.full" - - -{- $generalAttributes -The attributes described in this section are not specific to a particular operation but rather generic. They may be used in any Span they apply to. Particular operations may refer to or require some of these attributes. - -Specification: https://opentelemetry.io/docs/specs/semconv/general/attributes/ --} - - -{- $serverClientSharedNetworkAttributes -These attributes may be used to describe the client and server in a connection-based network interaction where there is one side that initiates the connection (the client is the side that initiates the connection). This covers all TCP network interactions since TCP is connection-based and one side initiates the connection (an exception is made for peer-to-peer communication over TCP where the “user-facing” surface of the protocol \/ API does not expose a clear notion of client and server). This also covers UDP network interactions where one side initiates the interaction, e.g. QUIC (HTTP\/3) and DNS. --} - - -{- | Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. - -Recomended. --} -server_address :: Key Text -server_address = "server.address" - - -{- | Server port number. - -Recomended. --} -server_port :: Key Int64 -server_port = "server.port" - - -{- | Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. - -Recomended. --} -client_address :: Key Text -client_address = "client.address" - - -{- | Client port number. - -Recomended. --} -client_port :: Key Int64 -client_port = "client.port" - - -{- $sourceAndDestinationAttributes -These attributes may be used to describe the sender and receiver of a network exchange\/packet. These should be used when there is no client\/server relationship between the two sides, or when that relationship is unknown. This covers low-level network interactions (e.g. packet tracing) where you don’t know if there was a connection or which side initiated it. This also covers unidirectional UDP flows and peer-to-peer communication where the “user-facing” surface of the protocol \/ API does not expose a clear notion of client and server. --} - - -{- | Source address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. - -Recomended. --} -source_address :: Key Text -source_address = "source.address" - - -{- | Source port number. - -Recomended. --} -source_port :: Key Int64 -source_port = "source.port" - - -{- | Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. - -Recomended. --} -destination_address :: Key Text -destination_address = "destination.address" - - -{- | Destination port number. - -Recomended. --} -destination_port :: Key Int64 -destination_port = "destination.port" - - -{- $generalRemoteServiceAttributes -This attribute may be used for any operation that accesses some remote service. Users can define what the name of a service is based on their particular semantics in their distributed system. Instrumentations SHOULD provide a way for users to configure this name. --} - - -{- | The @service.name@ of the remote service. SHOULD be equal to the actual @service.name@ resource attribute of the remote service if any. - -Recomended. --} -peer_service :: Key Text -peer_service = "peer.service" - - -{- | Username or client_id extracted from the access token or [Authorization](https://tools.ietf.org/html/rfc7235#section-4.2) header in the inbound request from outside the system. - -Recomended. --} -enduser_id :: Key Text -enduser_id = "enduser.id" - - -{- | Actual\/assumed role the client is making the request under extracted from token or application security context. - -Recomended. --} -enduser_role :: Key Text -enduser_role = "enduser.role" - - -{- | Scopes or granted authorities the client currently possesses extracted from token or application security context. The value would come from the scope associated with an [OAuth 2.0 Access](https://tools.ietf.org/html/rfc6749#section-3.3) Token or an attribute value in a [SAML 2.0 Assertion](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html). - -Recomended. --} -enduser_scope :: Key Text -enduser_scope = "enduser.scope" - - -{- $eventAttributes -Specification: https://opentelemetry.io/docs/specs/semconv/general/events/ --} - - -{- $generalLogIdentificationAttributes -Events are recorded as LogRecords that are shaped in a special way: Event LogRecords have the attributes event.domain and event.name (and possibly other LogRecord attributes). --} - - -{- | The domain identifies the business context for the events. - -Required. --} -event_domain :: Key Text -event_domain = "event.domain" - - -{- | The name identifies the event. - -Required. --} -event_name :: Key Text -event_name = "event.name" - - -{- $generalLogsAttributes -The attributes described in this section are rather generic. They may be used in any Log Record they apply to. - -Specification: https://opentelemetry.io/docs/specs/semconv/general/logs/ --} - - -{- | A unique identifier for the Log Record. - -Opt-In. --} -log_record_uid :: Key Text -log_record_uid = "log.record.uid" - - -{- $logMedia -This section describes attributes for log media in OpenTelemetry. Log media are mechanisms by which logs are transmitted. Types of media include files, streams, network protocols, and os-specific logging services such as journald and Windows Event Log. --} - - -{- | The basename of the file. - -Recommended. --} -log_file_name :: Key Text -log_file_name = "log.file.name" - - -{- | The basename of the file, with symlinks resolved. - -Opt-In. --} -log_file_nameResolved :: Key Text -log_file_nameResolved = "log.file.name_resolved" - - -{- | The full path to the file. - -Opt-In. --} -log_file_path :: Key Text -log_file_path = "log.file.path" - - -{- | The full path to the file, with symlinks resolved. - -Opt-In. --} -log_file_pathResolved :: Key Text -log_file_pathResolved = "log.file.path_resolved" - - -{- | The stream associated with the log. - -Opt-In. --} -log_iostream :: Key Text -log_iostream = "log.iostream" - - -{- | A unique id to identify a session. - -Opt-In. --} -session_id :: Key Text -session_id = "session.id" - - -{- | The previous @session.id@ for this user, when known. - -Opt-In. --} -session_previousId :: Key Text -session_previousId = "session.previous_id" - - -{- | Parent-child reference type. - -Recommended. --} -opentracing_refType :: Key Text -opentracing_refType = "opentracing.ref_type" - - -{- $awsSdk -This document defines semantic conventions to apply when instrumenting the AWS SDK. They map request or response parameters in AWS SDK API calls to attributes on a Span. The conventions have been collected over time based on feedback from AWS users of tracing and will continue to increase as new interesting conventions are found. - -Specification: https://opentelemetry.io/docs/specs/semconv/cloud-providers/aws-sdk/ --} - - -{- | The AWS request ID as returned in the response headers @x-amz-request-id@ or @x-amz-requestid@. - -Recomended. --} -aws_requestId :: Key Text -aws_requestId = "aws.request_id" - - -{- $databaseClientCalls -Span kind: MUST always be CLIENT. - -The span name SHOULD be set to a low cardinality value representing the statement executed on the database. It MAY be a stored procedure name (without arguments), DB statement without variable arguments, operation name, etc. Since SQL statements may have very high cardinality even without arguments, SQL spans SHOULD be named the following way, unless the statement is known to be of low cardinality: @db.operation@ @db.name.db.sql.table@, provided that @db.operation@ and @db.sql.table@ are available. If @db.sql.table@ is not available due to its semantics, the span SHOULD be named @db.operation@ @db.name@. It is not recommended to attempt any client-side parsing of @db.statement@ just to get these properties, they should only be used if the library being instrumented already provides them. When it’s otherwise impossible to get any meaningful span name, @db.name@ or the tech-specific database name MAY be used. - -Specification: https://opentelemetry.io/docs/specs/semconv/database/database-spans/ --} - - -{- | The connection string used to connect to the database. It is recommended to remove embedded credentials. - -Recommended. --} -db_connectionString :: Key Text -db_connectionString = "db.connection_string" - - -{- | An identifier for the database management system (DBMS) product being used. See the spec. for a list of well-known identifiers. - -Required. --} -db_system :: Key Text -db_system = "db.system" - - -{- | Username for accessing the database. - -Recomended. --} -db_user :: Key Text -db_user = "db.user" - - -{- -db.name string This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). [1] customers; main Conditionally Required: If applicable. -db.operation string The name of the operation being executed, e.g. the MongoDB command name such as findAndModify, or the SQL keyword. [2] findAndModify; HMSET; SELECT Conditionally Required: If db.statement is not applicable. -db.statement string The database statement being executed. SELECT * FROM wuser_table; SET mykey "WuValue" Recommended: [3] --} - -{- | This attribute is used to report the name of the database being accessed. For commands that switch the database, this should be set to the target database (even if the command fails). - -Conditionally Required: If applicable. --} -db_name :: Key Text -db_name = "db.name" - - -{- | The name of the operation being executed, e.g. the [MongoDB command name](https://docs.mongodb.com/manual/reference/command/#database-operations) such as @findAndModify@, or the SQL keyword. - -Conditionally Required: If @db.statement@ is not applicable. --} -db_operation :: Key Text -db_operation = "db.operation" - - -{- | The database statement being executed. - -Recommended. --} -db_statement :: Key Text -db_statement = "db.statement" - - -{- $redis -The Semantic Conventions for [Redis](https://redis.com/) extend and override the [Database Semantic Conventions](https://opentelemetry.io/docs/specs/semconv/database/database-spans/) that describe common database operations attributes in addition to the Semantic Conventions described on this page. - -@db.system@ MUST be set to @"redis"@. --} - - -{- | The index of the database being accessed as used in the [@SELECT@ command](https://redis.io/commands/select), provided as an integer. To be used instead of the generic @db.name@ attribute.} - -Conditionally Required: If other than the default database (@0@). --} -db_redis_databaseIndex :: Key Int64 -db_redis_databaseIndex = "db.redis.database_index" - - -{- $sqlDatabase -The SQL databases Semantic Conventions extend and override the [Database Semantic Conventions](https://opentelemetry.io/docs/specs/semconv/database/database-spans/) that describe common database operations attributes in addition to the Semantic Conventions described on this page. --} - - -{- | The name of the primary table that the operation is acting upon, including the database name (if applicable). - -Recommended. --} -db_sql_table :: Key Text -db_sql_table = "db.sql.table" - - -{- $httpMetrics -The conventions described in this section are HTTP specific. When HTTP operations occur, metric events about those operations will be generated and reported to provide insight into the operations. By adding HTTP attributes to metric events it allows for finely tuned filtering. - -Specification: https://opentelemetry.io/docs/specs/semconv/http/http-metrics/ --} - - -{- | Describes a class of error the operation ended with. - -Conditionally Required: If request has ended with an error. --} -error_type :: Key Text -error_type = "error.type" - - -{- $faas -Specification: https://opentelemetry.io/docs/specs/semconv/resource/faas/ --} - - -{- -faas.instance string The execution environment ID as a string, that will be potentially reused for other invocations to the same function/function version. [2] 2021/06/28/[$LATEST]2f399eb14537447da05ab2a2e39309de Recommended -faas.max_memory int The amount of memory available to the serverless function converted to Bytes. [3] 134217728 Recommended -faas.name string The name of the single function that this runtime instance executes. [4] my-function; myazurefunctionapp/some-function-name Required -faas.version string The immutable version of the function being executed. [5] 26; pinkfroid-00002 Recommended --} - -{- | The execution environment ID as a string, that will be potentially reused for other invocations to the same function\/function version. - -Recomended. --} -faas_instance :: Key Text -faas_instance = "faas.instance" - - -{- | The amount of memory available to the serverless function converted to Bytes. - -Recomended. --} -faas_maxMemory :: Key Int64 -faas_maxMemory = "faas.max_memory" - - -{- | The name of the single function that this runtime instance executes. - -Required. --} -faas_name :: Key Text -faas_name = "faas.name" - - -{- | The immutable version of the function being executed. - -Recomended. --} -faas_version :: Key Text -faas_version = "faas.version" - - -{- $tbd - -To be done. --} diff --git a/cabal.project b/cabal.project index d9f007b1..93e01593 100644 --- a/cabal.project +++ b/cabal.project @@ -2,6 +2,7 @@ packages: api , sdk , otlp + , semantic-conventions , examples/aws-s3 , examples/grpc-echo , examples/hdbc-mysql diff --git a/hie.yaml b/hie.yaml index 49b9f716..9681f3ec 100644 --- a/hie.yaml +++ b/hie.yaml @@ -16,6 +16,20 @@ cradle: - "-package base" - "-package Cabal" - "-package filepath" + - path: "semantic-conventions/Setup.hs" + config: + cradle: + direct: + arguments: + - "-package aeson" + - "-package base" + - "-package Cabal" + - "-package Glob" + - "-package directory" + - "-package filepath" + - "-package yaml" + - "-package text" + - "-package vector" - path: . config: cradle: @@ -200,6 +214,9 @@ cradle: - path: "sdk/test" component: "hs-opentelemetry-sdk:test:hs-opentelemetry-sdk-test" + - path: "semantic-conventions/gen" + component: "lib:hs-opentelemetry-semantic-conventions" + - path: "utils/exceptions/src" component: "lib:hs-opentelemetry-utils-exceptions" diff --git a/instrumentation/amazonka/hs-opentelemetry-instrumentation-amazonka.cabal b/instrumentation/amazonka/hs-opentelemetry-instrumentation-amazonka.cabal index d5ddf231..199efdc0 100644 --- a/instrumentation/amazonka/hs-opentelemetry-instrumentation-amazonka.cabal +++ b/instrumentation/amazonka/hs-opentelemetry-instrumentation-amazonka.cabal @@ -19,6 +19,7 @@ library other-modules: Paths_hs_opentelemetry_instrumentation_amazonka autogen-modules: Paths_hs_opentelemetry_instrumentation_amazonka build-depends: hs-opentelemetry-api, + hs-opentelemetry-semantic-conventions, amazonka >= 2, http-client, text, diff --git a/instrumentation/amazonka/src/OpenTelemetry/Instrumentation/Amazonka.hs b/instrumentation/amazonka/src/OpenTelemetry/Instrumentation/Amazonka.hs index 578b5983..f846c108 100644 --- a/instrumentation/amazonka/src/OpenTelemetry/Instrumentation/Amazonka.hs +++ b/instrumentation/amazonka/src/OpenTelemetry/Instrumentation/Amazonka.hs @@ -37,9 +37,9 @@ import Data.Typeable (Typeable) import Data.Version (showVersion) import GHC.Stack (HasCallStack, withFrozenCallStack) import qualified Network.HTTP.Client as HTTP -import qualified OpenTelemetry.Attributes.Key as Otel import qualified OpenTelemetry.Attributes.Map as Otel import qualified OpenTelemetry.Context.ThreadLocal as Otel +import qualified OpenTelemetry.SemanticConventions as Otel import qualified OpenTelemetry.Trace.Core as Otel import Paths_hs_opentelemetry_instrumentation_amazonka (version) diff --git a/instrumentation/hdbc-mysql/hs-opentelemetry-instrumentation-HDBC-mysql.cabal b/instrumentation/hdbc-mysql/hs-opentelemetry-instrumentation-HDBC-mysql.cabal index bc619572..38293ee4 100644 --- a/instrumentation/hdbc-mysql/hs-opentelemetry-instrumentation-HDBC-mysql.cabal +++ b/instrumentation/hdbc-mysql/hs-opentelemetry-instrumentation-HDBC-mysql.cabal @@ -18,6 +18,7 @@ library exposed-modules: OpenTelemetry.Instrumentation.HDBC.MySQL build-depends: hs-opentelemetry-api, hs-opentelemetry-instrumentation-HDBC, + hs-opentelemetry-semantic-conventions, HDBC-mysql, text, ghc-options: -Wno-name-shadowing diff --git a/instrumentation/hdbc-mysql/src/OpenTelemetry/Instrumentation/HDBC/MySQL.hs b/instrumentation/hdbc-mysql/src/OpenTelemetry/Instrumentation/HDBC/MySQL.hs index 74166710..5c58a0a6 100644 --- a/instrumentation/hdbc-mysql/src/OpenTelemetry/Instrumentation/HDBC/MySQL.hs +++ b/instrumentation/hdbc-mysql/src/OpenTelemetry/Instrumentation/HDBC/MySQL.hs @@ -11,9 +11,9 @@ module OpenTelemetry.Instrumentation.HDBC.MySQL ( import qualified Data.Text as Text import qualified Database.HDBC.MySQL as Orig -import qualified OpenTelemetry.Attributes as Attr import qualified OpenTelemetry.Attributes.Map as Attr import qualified OpenTelemetry.Instrumentation.HDBC as Otel +import qualified OpenTelemetry.SemanticConventions as Attr import qualified OpenTelemetry.Trace.Core as Otel diff --git a/instrumentation/hdbc/hs-opentelemetry-instrumentation-HDBC.cabal b/instrumentation/hdbc/hs-opentelemetry-instrumentation-HDBC.cabal index 58b5e53c..9dc87735 100644 --- a/instrumentation/hdbc/hs-opentelemetry-instrumentation-HDBC.cabal +++ b/instrumentation/hdbc/hs-opentelemetry-instrumentation-HDBC.cabal @@ -17,6 +17,7 @@ library hs-source-dirs: src exposed-modules: OpenTelemetry.Instrumentation.HDBC build-depends: hs-opentelemetry-api, + hs-opentelemetry-semantic-conventions, HDBC, data-default-class, text diff --git a/instrumentation/hdbc/src/OpenTelemetry/Instrumentation/HDBC.hs b/instrumentation/hdbc/src/OpenTelemetry/Instrumentation/HDBC.hs index 8234ee59..2e00a1f4 100644 --- a/instrumentation/hdbc/src/OpenTelemetry/Instrumentation/HDBC.hs +++ b/instrumentation/hdbc/src/OpenTelemetry/Instrumentation/HDBC.hs @@ -40,6 +40,7 @@ import GHC.Generics (Generic) import GHC.Stack (withFrozenCallStack) import qualified OpenTelemetry.Attributes as Attr import qualified OpenTelemetry.Attributes.Map as Attr +import qualified OpenTelemetry.SemanticConventions as Attr import qualified OpenTelemetry.Trace.Core as Otel diff --git a/instrumentation/herp-logger-datadog/hs-opentelemetry-instrumentation-herp-logger-datadog.cabal b/instrumentation/herp-logger-datadog/hs-opentelemetry-instrumentation-herp-logger-datadog.cabal index 7b2b1a66..d9ba955b 100644 --- a/instrumentation/herp-logger-datadog/hs-opentelemetry-instrumentation-herp-logger-datadog.cabal +++ b/instrumentation/herp-logger-datadog/hs-opentelemetry-instrumentation-herp-logger-datadog.cabal @@ -17,6 +17,7 @@ library hs-source-dirs: src exposed-modules: OpenTelemetry.Instrumentation.Herp.Logger.Datadog build-depends: hs-opentelemetry-api, + hs-opentelemetry-semantic-conventions, hs-opentelemetry-vendor-datadog, aeson, herp-logger, diff --git a/instrumentation/herp-logger-datadog/src/OpenTelemetry/Instrumentation/Herp/Logger/Datadog.hs b/instrumentation/herp-logger-datadog/src/OpenTelemetry/Instrumentation/Herp/Logger/Datadog.hs index 1e2c5f55..bbed993a 100644 --- a/instrumentation/herp-logger-datadog/src/OpenTelemetry/Instrumentation/Herp/Logger/Datadog.hs +++ b/instrumentation/herp-logger-datadog/src/OpenTelemetry/Instrumentation/Herp/Logger/Datadog.hs @@ -73,6 +73,7 @@ import qualified OpenTelemetry.Attributes.Map as Otel import qualified OpenTelemetry.Context as Otel import qualified OpenTelemetry.Context.ThreadLocal as Otel import qualified OpenTelemetry.Resource as Otel +import qualified OpenTelemetry.SemanticConventions as Otel import qualified OpenTelemetry.Trace.Core as Otel import qualified OpenTelemetry.Vendor.Datadog as Datadog diff --git a/instrumentation/http-client/hs-opentelemetry-instrumentation-http-client.cabal b/instrumentation/http-client/hs-opentelemetry-instrumentation-http-client.cabal index 1eedf42a..d42c2a73 100644 --- a/instrumentation/http-client/hs-opentelemetry-instrumentation-http-client.cabal +++ b/instrumentation/http-client/hs-opentelemetry-instrumentation-http-client.cabal @@ -37,6 +37,7 @@ library base >=4.7 && <5 , case-insensitive , hs-opentelemetry-api ==0.1.* + , hs-opentelemetry-semantic-conventions , http-client , http-types , text @@ -58,6 +59,7 @@ test-suite hs-opentelemetry-instrumentation-http-client-test , case-insensitive , hs-opentelemetry-api ==0.1.* , hs-opentelemetry-instrumentation-http-client + , hs-opentelemetry-semantic-conventions , http-client , http-types , text diff --git a/instrumentation/http-client/package.yaml b/instrumentation/http-client/package.yaml index 77303536..5b754063 100644 --- a/instrumentation/http-client/package.yaml +++ b/instrumentation/http-client/package.yaml @@ -22,6 +22,7 @@ dependencies: - base >= 4.7 && < 5 - case-insensitive - hs-opentelemetry-api == 0.1.* +- hs-opentelemetry-semantic-conventions - http-client - http-types - text diff --git a/instrumentation/http-client/src/OpenTelemetry/Instrumentation/HttpClient.hs b/instrumentation/http-client/src/OpenTelemetry/Instrumentation/HttpClient.hs index caa0c7e6..b6f784de 100644 --- a/instrumentation/http-client/src/OpenTelemetry/Instrumentation/HttpClient.hs +++ b/instrumentation/http-client/src/OpenTelemetry/Instrumentation/HttpClient.hs @@ -23,10 +23,10 @@ import Data.Version (showVersion) import GHC.Stack (HasCallStack, withFrozenCallStack) import qualified Network.HTTP.Client as Orig import qualified Network.HTTP.Types.Status as HT -import qualified OpenTelemetry.Attributes.Key as Otel import qualified OpenTelemetry.Attributes.Map as Otel import qualified OpenTelemetry.Context.ThreadLocal as Otel import qualified OpenTelemetry.Propagator as Otel +import qualified OpenTelemetry.SemanticConventions as Otel import qualified OpenTelemetry.Trace.Core as Otel import Paths_hs_opentelemetry_instrumentation_http_client (version) diff --git a/semantic-conventions/.gitignore b/semantic-conventions/.gitignore new file mode 100644 index 00000000..e8e450be --- /dev/null +++ b/semantic-conventions/.gitignore @@ -0,0 +1 @@ +gen/ diff --git a/semantic-conventions/Setup.hs b/semantic-conventions/Setup.hs new file mode 100644 index 00000000..b607be19 --- /dev/null +++ b/semantic-conventions/Setup.hs @@ -0,0 +1,689 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE DuplicateRecordFields #-} +{-# LANGUAGE GeneralisedNewtypeDeriving #-} +{-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE OverloadedStrings #-} +{-# OPTIONS_GHC -Wall #-} +{-# OPTIONS_GHC -Wcompat #-} +{-# OPTIONS_GHC -Widentities #-} +{-# OPTIONS_GHC -Wincomplete-record-updates #-} +{-# OPTIONS_GHC -Wincomplete-uni-patterns #-} +{-# OPTIONS_GHC -Winvalid-haddock #-} +{-# OPTIONS_GHC -Wmissing-deriving-strategies #-} +{-# OPTIONS_GHC -Wmissing-export-lists #-} +{-# OPTIONS_GHC -Wmissing-exported-signatures #-} +{-# OPTIONS_GHC -Wmissing-home-modules #-} +{-# OPTIONS_GHC -Wmissing-import-lists #-} +{-# OPTIONS_GHC -Wmonomorphism-restriction #-} +{-# OPTIONS_GHC -Wno-name-shadowing #-} +{-# OPTIONS_GHC -Wredundant-constraints #-} +{-# OPTIONS_GHC -Wunused-packages #-} + + +#if __GLASGOW_HASKELL__ >= 902 +{-# OPTIONS_GHC -Wmissing-kind-signatures #-} +{-# OPTIONS_GHC -Woperator-whitespace #-} +{-# OPTIONS_GHC -Wredundant-bang-patterns #-} +#endif + +module Main (main) where + +import Control.Applicative (Alternative ((<|>))) +import qualified Data.Aeson as Json +import qualified Data.Aeson.KeyMap as JsonMap +import qualified Data.Char as Char +import Data.Foldable (Foldable (fold)) +import Data.Functor ((<&>)) +import Data.Int (Int64) +import qualified Data.List as List +import Data.Maybe (fromMaybe) +import Data.Text (Text) +import qualified Data.Text as Text +import Data.Traversable (for) +import Data.Vector (Vector) +import qualified Data.Vector as Vector +import qualified Data.Yaml as Yaml +import Distribution.Simple (Args, defaultMainWithHooks, simpleUserHooks) +import qualified Distribution.Simple +import Distribution.Simple.Setup (BuildFlags) +import Distribution.Types.HookedBuildInfo (HookedBuildInfo, emptyHookedBuildInfo) +import System.Directory (createDirectoryIfMissing) +import System.FilePath (()) +import qualified System.FilePath.Glob as Glob +import System.IO (IOMode (WriteMode), hPutStrLn, hSetNewlineMode, noNewlineTranslation, stderr, withFile) +import Prelude ( + Applicative (pure, (<*>)), + Bool (False, True), + Eq, + FilePath, + Functor (fmap), + IO, + Int, + Maybe (Just, Nothing), + MonadFail (fail), + Monoid (mempty), + Ord, + Read, + Semigroup ((<>)), + Show (show), + String, + Traversable (traverse), + floor, + maybe, + ($), + (++), + (.), + (<$>), + ) +import qualified Prelude + + +#if MIN_VERSION_text(2,1,0) +import qualified Data.Text.IO.Utf8 as TextIO +#else +import qualified Data.Text.IO as TextIO +#endif + + +newtype Model + = Model Groups + deriving stock (Show, Read, Eq, Ord) + + +instance Json.FromJSON Model where + parseJSON (Json.Object o) = Model <$> o Json..: "groups" + parseJSON _ = fail "expected an object" + + +newtype Groups + = Groups (Vector Semconv) + deriving stock (Show, Read, Eq, Ord) + deriving newtype (Json.FromJSON) + + +data Semconv = Semconv + { id :: Text + , typ :: Convtype + , brief :: Brief + , note :: Maybe Note + , prefix :: Maybe Prefix + , extends :: Maybe Extends + , stability :: Maybe Stability + , deprecated :: Maybe Deprecated + , attributes :: Vector Attribute + -- ^ The spec says non-empty, but maybe empty actually. + , constraints :: Vector Constraint + , specificfields :: Maybe Specificfields + } + deriving stock (Show, Read, Eq, Ord) + + +instance Json.FromJSON Semconv where + parseJSON (Json.Object o) = do + (typ, spacificfields) <- + case JsonMap.lookup "type" o of + Just "span" -> pure (SpanType, Nothing) + Just "resource" -> do + specificfields <- + Spanfields <$> (fromMaybe mempty <$> o Json..:? "events") <*> o Json..:? "span_kind" + pure (ResourceType, Just specificfields) + Just "event" -> do + specificfields <- Eventfields <$> o Json..:? "name" + pure (EventType, Just specificfields) + Just "metric" -> do + specificfields <- Metricfields <$> o Json..: "metric_name" <*> o Json..: "instrument" <*> o Json..: "unit" + pure (MetricType, Just specificfields) + Just "metric_group" -> pure (MetricGroupType, Nothing) + Just "scope" -> pure (ScopeType, Nothing) + Just "attribute_group" -> pure (AttributeGroupType, Nothing) + Nothing -> pure (SpanType, Nothing) + _ -> fail "expected a string with value of \"span\", \"resource\", \"event\", \"metric\", \"metric_group\", \"scope\", or \"attribute_group\"" + Semconv + <$> o Json..: "id" + <*> pure typ + <*> o Json..: "brief" + <*> o Json..:? "note" + <*> o Json..:? "prefix" + <*> o Json..:? "extends" + <*> o Json..:? "stability" + <*> o Json..:? "deprecated" + <*> (fromMaybe mempty <$> o Json..:? "attributes") + <*> (fromMaybe mempty <$> o Json..:? "constraints") + <*> pure spacificfields + parseJSON _ = fail "expected an object" + + +type Id = Text + + +data Convtype + = SpanType + | ResourceType + | EventType + | MetricType + | MetricGroupType + | ScopeType + | AttributeGroupType + deriving stock (Show, Read, Eq, Ord, Prelude.Enum) + + +type Note = Text + + +type Brief = Text + + +type Prefix = Text + + +type Extends = Text + + +data Stability = Deprecated | Experimental | Stable deriving stock (Show, Read, Eq, Ord, Prelude.Enum) + + +instance Json.FromJSON Stability where + parseJSON (Json.String "deprecated") = pure Deprecated + parseJSON (Json.String "experimental") = pure Experimental + parseJSON (Json.String "stable") = pure Stable + parseJSON _ = fail "expected a string with value of \"deprecated\", \"experimental\", or \"stable\"" + + +type Deprecated = Text + + +data Attribute + = AttributeDef + { defFields :: AttributeDefFields + , tag :: Maybe Tag + , stability :: Maybe Stability + , deprecated :: Maybe Deprecated + , requirementLevel :: Maybe RequirementLevel + , samplingRelevant :: Maybe SamplingRelevant + , note :: Maybe Note + } + | AttributeRef + { refFields :: AttributeRefFields + , tag :: Maybe Tag + , stability :: Maybe Stability + , deprecated :: Maybe Deprecated + , requirementLevel :: Maybe RequirementLevel + , samplingRelevant :: Maybe SamplingRelevant + , note :: Maybe Note + } + deriving stock (Show, Read, Eq, Ord) + + +instance Json.FromJSON Attribute where + parseJSON (Json.Object o) = + case (JsonMap.lookup "id" o, JsonMap.lookup "ref" o) of + (Just id_, Nothing) -> + AttributeDef + <$> ( AttributeDefFields + <$> Json.parseJSON id_ + <*> o Json..: "type" + <*> o Json..: "brief" + <*> (fromMaybe mempty <$> o Json..:? "examples") + ) + <*> o Json..:? "tag" + <*> o Json..:? "stability" + <*> o Json..:? "deprecated" + <*> o Json..:? "requirement_level" + <*> o Json..:? "sampling_relevant" + <*> o Json..:? "note" + (Nothing, Just ref) -> + AttributeRef + <$> ( AttributeRefFields + <$> Json.parseJSON ref + <*> o Json..:? "brief" + <*> (fromMaybe mempty <$> o Json..:? "examples") + ) + <*> o Json..:? "tag" + <*> o Json..:? "stability" + <*> o Json..:? "deprecated" + <*> o Json..:? "requirement_level" + <*> o Json..:? "sampling_relevant" + <*> o Json..:? "note" + (Just _, Just _) -> fail "expected either an object with a field of \"id\" or \"ref\"" + (Nothing, Nothing) -> fail "expected an object with a field of \"id\" or \"ref\"" + parseJSON _ = fail "expected an object" + + +data AttributeDefFields = AttributeDefFields + { id :: Id + , typ :: Type + , brief :: Brief + , examples :: OneOrSome Example + -- ^ The spec says non-empty, but maybe empty actually. + } + deriving stock (Show, Read, Eq, Ord) + + +data AttributeRefFields = AttributeRefFields + { ref :: Id + , brief :: Maybe Brief + , examples :: OneOrSome Example + } + deriving stock (Show, Read, Eq, Ord) + + +data Type + = TypeSimple SimpleType + | TypeTemplate SimpleType + | TypeEnum Enum + deriving stock (Show, Read, Eq, Ord) + + +instance Json.FromJSON Type where + parseJSON (Json.String "string") = pure $ TypeSimple StringType + parseJSON (Json.String "int") = pure $ TypeSimple IntType + parseJSON (Json.String "double") = pure $ TypeSimple DoubleType + parseJSON (Json.String "boolean") = pure $ TypeSimple BooleanType + parseJSON (Json.String "string[]") = pure $ TypeSimple StringArrayType + parseJSON (Json.String "int[]") = pure $ TypeSimple IntArrayType + parseJSON (Json.String "double[]") = pure $ TypeSimple DoubleArrayType + parseJSON (Json.String "boolean[]") = pure $ TypeSimple BooleanArrayType + parseJSON (Json.String "template[string]") = pure $ TypeTemplate StringType + parseJSON (Json.String "template[int]") = pure $ TypeTemplate IntType + parseJSON (Json.String "template[double]") = pure $ TypeTemplate DoubleType + parseJSON (Json.String "template[boolean]") = pure $ TypeTemplate BooleanType + parseJSON (Json.String "template[string[]]") = pure $ TypeTemplate StringArrayType + parseJSON (Json.String "template[int[]]") = pure $ TypeTemplate IntArrayType + parseJSON (Json.String "template[double[]]") = pure $ TypeTemplate DoubleArrayType + parseJSON (Json.String "template[boolean[]]") = pure $ TypeTemplate BooleanArrayType + parseJSON (Json.Object o) = TypeEnum <$> Json.parseJSON (Json.Object o) + parseJSON _ = fail "expected a string with specific values or an object" + + +data SimpleType + = StringType + | IntType + | DoubleType + | BooleanType + | StringArrayType + | IntArrayType + | DoubleArrayType + | BooleanArrayType + deriving stock (Show, Read, Eq, Ord, Prelude.Enum) + + +data Enum = Enum + { allowCustomValues :: Maybe Bool + , members :: Vector Member + -- ^ non-empty + } + deriving stock (Show, Read, Eq, Ord) + + +instance Json.FromJSON Enum where + parseJSON (Json.Object o) = + Enum + <$> o Json..:? "allow_custom_values" + <*> o Json..: "members" + parseJSON _ = fail "expected an object" + + +data Member = Member + { id :: Id + , value :: Value + , brief :: Maybe Brief + , note :: Maybe Note + } + deriving stock (Show, Read, Eq, Ord) + + +instance Json.FromJSON Member where + parseJSON (Json.Object o) = + Member + <$> o Json..: "id" + <*> o Json..: "value" + <*> o Json..:? "brief" + <*> o Json..:? "note" + parseJSON _ = fail "expected an object" + + +data Value + = StringValue Text + | IntValue Int64 + | BooleanValue Bool + deriving stock (Show, Read, Eq, Ord) + + +instance Json.FromJSON Value where + parseJSON (Json.String s) = pure $ StringValue s + parseJSON (Json.Number n) = pure $ IntValue $ floor n + parseJSON (Json.Bool b) = pure $ BooleanValue b + parseJSON _ = fail "expected a string, number, or boolean" + + +data RequirementLevel + = Required + | ConditionallyRequired Text + | Recommended (Maybe Text) + | OptIn + deriving stock (Show, Read, Eq, Ord) + + +instance Json.FromJSON RequirementLevel where + parseJSON (Json.String "required") = pure Required + parseJSON (Json.String "recommended") = pure $ Recommended Nothing + parseJSON (Json.Object o) = + ConditionallyRequired <$> o Json..: "conditionally_required" + <|> Recommended . Just <$> o Json..: "recommended" + parseJSON (Json.String "opt_in") = pure OptIn + parseJSON _ = fail "expected a string with value of \"required\", \"recommended\", or \"opt_in\", or an object with a field of \"conditionally_required\" or \"recommended\"" + + +type SamplingRelevant = Bool + + +newtype Example = Example Text deriving stock (Show, Read, Eq, Ord) + + +instance Json.FromJSON Example where + parseJSON o@(Json.String _) = Example <$> Json.parseJSON o + parseJSON (Json.Number n) = pure $ Example $ Text.pack $ show n + parseJSON (Json.Bool True) = pure $ Example "true" + parseJSON (Json.Bool False) = pure $ Example "false" + parseJSON _ = fail "expected a string, number, or boolean" + + +type Tag = Text + + +data Constraint + = -- | non-empty + AnyOf (Vector Id) + | Include Id + deriving stock (Show, Read, Eq, Ord) + + +instance Json.FromJSON Constraint where + parseJSON (Json.Object o) = + AnyOf <$> o Json..: "any_of" <|> Include <$> o Json..: "include" + parseJSON _ = fail "expected an object" + + +data Specificfields + = Spanfields {events :: Vector Id, spanKind :: Maybe SpanKind} + | Eventfields {name :: Maybe Name} + | Metricfields {metricName :: MetricName, instrument :: Instrument, unit :: Unit} + deriving stock (Show, Read, Eq, Ord) + + +data SpanKind + = ClientKind + | ServerKind + | ProducerKind + | ConsumerKind + | InternalKind + deriving stock (Show, Read, Eq, Ord, Prelude.Enum) + + +instance Json.FromJSON SpanKind where + parseJSON (Json.String "client") = pure ClientKind + parseJSON (Json.String "server") = pure ServerKind + parseJSON (Json.String "producer") = pure ProducerKind + parseJSON (Json.String "consumer") = pure ConsumerKind + parseJSON (Json.String "internal") = pure InternalKind + parseJSON _ = fail "expected a string with value of \"client\", \"server\", \"producer\", \"consumer\", or \"internal\"" + + +type Name = Text + + +type MetricName = Text + + +data Instrument + = Counter + | Histogram + | Gauge + | Updowncounter + deriving stock (Show, Read, Eq, Ord, Prelude.Enum) + + +instance Json.FromJSON Instrument where + parseJSON (Json.String "counter") = pure Counter + parseJSON (Json.String "histogram") = pure Histogram + parseJSON (Json.String "gauge") = pure Gauge + parseJSON (Json.String "updowncounter") = pure Updowncounter + parseJSON _ = fail "expected a string with value of \"counter\", \"histogram\", \"gauge\", or \"updowncounter\"" + + +type Unit = Text + + +newtype OneOrSome a + = OneOrSome (Vector a) + deriving stock (Show, Read, Eq, Ord) + deriving newtype (Semigroup, Monoid) + + +instance Json.FromJSON a => Json.FromJSON (OneOrSome a) where + parseJSON (Json.Array a) = OneOrSome <$> traverse Json.parseJSON a + parseJSON o = OneOrSome . Vector.singleton <$> Json.parseJSON o + + +main :: IO () +main = defaultMainWithHooks simpleUserHooks {Distribution.Simple.preBuild = preBuild} + + +preBuild :: Args -> BuildFlags -> IO HookedBuildInfo +preBuild _ _ = do + let + yamlPattern = Glob.compile "model/model/**/*.y*ml" + targetDirectory :: FilePath + targetDirectory = "gen/OpenTelemetry/" + targetFile = targetDirectory "SemanticConventions.hs" + yamlFiles <- Glob.globDir1 yamlPattern "." + models <- + for yamlFiles $ \yamlFile -> do + printLog $ "processing " ++ yamlFile + Yaml.decodeFileThrow yamlFile :: IO Model + createDirectoryIfMissing True targetDirectory + withFile targetFile WriteMode $ \targetHandle -> do + hSetNewlineMode targetHandle noNewlineTranslation + let + (exports, bodies) = + Vector.unzip $ do + Model (Groups semconvs) <- Vector.fromList models + Semconv {id, prefix, attributes, brief, note, stability, deprecated} <- semconvs + let + id' = convertId id + body = + comment + <$> fold + [ if Text.null brief then [] else [convertMarkupFromMarkdownToHaddock brief] + , fieldLine stability $ ("Stability: " <>) . convertStability + , fieldLine deprecated $ ("Deprecated: " <>) + , fieldLines note $ \n -> + [ "==== Note" + , convertMarkupFromMarkdownToHaddock n + ] + ] + (exports, headers, bodies) = + Vector.unzip3 $ + attributes <&> \attribute -> + case attribute of + AttributeDef {defFields = AttributeDefFields {id, typ, brief}, stability, deprecated, requirementLevel, note} -> + let + (id', hid) = + case prefix of + Nothing -> (id, convertId id) + Just p -> (p <> "." <> id, convertId p <> "_" <> convertId id) + in + ( [hid <> ","] + , comment + <$> fold + [ ["- '" <> hid <> "'"] + , fieldLine stability $ indent 1 . ("Stability: " <>) . convertStability + , fieldLine deprecated $ indent 1 . ("Deprecated: " <>) + , fieldLine requirementLevel $ indent 1 . ("Requirement level: " <>) . convertRequirementLevel + , [""] + ] + , fold + [ + [ "-- |" + , comment $ convertMarkupFromMarkdownToHaddock brief + ] + , fieldLines note $ \n -> comment <$> ["==== Note", convertMarkupFromMarkdownToHaddock n] + , + [ hid <> " :: " <> convertType typ + , hid <> " = " <> convertIdToKey typ id' + ] + ] + ) + AttributeRef {refFields = AttributeRefFields {ref, brief}, stability, deprecated, requirementLevel, note} -> + let href = convertId ref + in ( [] + , comment + <$> fold + [ ["- '" <> href <> "'"] + , fieldLine brief $ indent 1 . convertMarkupFromMarkdownToHaddock + , fieldLine stability $ indent 1 . ("Stability: " <>) . convertStability + , fieldLine deprecated $ indent 1 . ("Deprecated: " <>) + , fieldLine requirementLevel $ indent 1 . ("Requirement level: " <>) . convertRequirementLevel + , fieldLines note $ \n -> + [ indent 1 $ "==== Note" + , indent 1 $ convertMarkupFromMarkdownToHaddock n + ] + , [""] + ] + , [] + ) + Vector.cons + ( + [ "-- * " <> id + , "-- $" <> id' + , "" + ] + , fold + [ ["-- $" <> id'] + , body + , ["--"] + , if Vector.null headers + then [] + else + ["-- === Attributes"] + ++ fold (Vector.toList headers) + ] + ) + $ Vector.zip exports bodies + TextIO.hPutStrLn targetHandle $ + Text.unlines $ + fold + [ + [ "{-# LANGUAGE DerivingStrategies #-}" + , "{-# LANGUAGE DeriveGeneric #-}" + , "{-# LANGUAGE OverloadedStrings #-}" + , "-- | This module is a OpenTelemetry Semantic Conventions for Haskell." + , "-- This is automatically generated" + , "-- based on [semantic-conventions](https://github.com/open-telemetry/semantic-conventions/) v1.24." + , "--" + , "-- This module's version A.B.X.Y means that A.B is the version of the original semantic-conventions," + , "-- and X.Y is the version of this module." + , "module OpenTelemetry.SemanticConventions (" + ] + , fold exports + , + [ ") where" + , "import Data.Text (Text)" + , "import Data.Int (Int64)" + , "import OpenTelemetry.Attributes.Key (Key (Key))" + , "{-# ANN module (\"HLint: ignore Use camelCase\" :: String) #-}" + ] + , fold $ List.intersperse [""] $ Vector.toList bodies + ] + pure emptyHookedBuildInfo + + +convertMarkupFromMarkdownToHaddock :: Text -> Text +convertMarkupFromMarkdownToHaddock = + Text.pack . conv . Text.unpack + where + conv [] = [] + conv ('*' : '*' : rest) = '_' : '_' : conv rest + conv ('*' : rest) = '*' : conv rest + conv ('`' : rest) = '@' : conv rest + conv ('/' : rest) = '\\' : '/' : conv rest + conv ('@' : rest) = '\\' : '@' : conv rest + conv ('<' : rest) = '\\' : '<' : conv rest + conv ('>' : rest) = '\\' : '>' : conv rest + conv ('\'' : rest) = '\\' : '\'' : conv rest + conv (c : rest) = c : conv rest + + +convertId :: Id -> Text +convertId = + Text.pack . conv False . Text.unpack + where + conv :: + Bool -> + -- \^ make it upper? ie. next to '_'? + String -> + String + conv _ [] = [] + conv True (c : rest) = Char.toUpper c : conv False rest + conv False ('_' : rest) = conv True rest + conv False ('.' : rest) = '_' : conv False rest + conv False (c : rest) = c : conv False rest + + +convertType :: Type -> Text +convertType (TypeSimple t) = "Key " <> convertSimpleType t +convertType (TypeTemplate t) = "Text -> Key " <> convertSimpleType t +convertType (TypeEnum _) = "Key Text" + + +convertSimpleType :: SimpleType -> Text +convertSimpleType StringType = "Text" +convertSimpleType IntType = "Int64" +convertSimpleType DoubleType = "Double" +convertSimpleType BooleanType = "Bool" +convertSimpleType StringArrayType = "[Text]" +convertSimpleType IntArrayType = "[Int64]" +convertSimpleType DoubleArrayType = "[Double]" +convertSimpleType BooleanArrayType = "[Bool]" + + +convertIdToKey :: Type -> Id -> Text +convertIdToKey (TypeTemplate _) id = "\\k -> Key $ \"" <> id <> ".\" <> k" +convertIdToKey _ id = "Key \"" <> id <> "\"" + + +convertStability :: Stability -> Text +convertStability Deprecated = "deprecated" +convertStability Experimental = "experimental" +convertStability Stable = "stable" + + +convertRequirementLevel :: RequirementLevel -> Text +convertRequirementLevel Required = "required" +convertRequirementLevel (ConditionallyRequired s) = "conditionally required: " <> convertMarkupFromMarkdownToHaddock s +convertRequirementLevel (Recommended (Just s)) = "recommended: " <> convertMarkupFromMarkdownToHaddock s +convertRequirementLevel (Recommended Nothing) = "recommended" +convertRequirementLevel OptIn = "opt-in" + + +comment :: Text -> Text +comment "" = "--" +comment s = Text.intercalate "\n" $ fmap ("-- " <>) $ Text.lines s + + +indent :: Int -> Text -> Text +indent n "" = Text.replicate n " " +indent n s = Text.intercalate "\n" $ fmap (Text.replicate n " " <>) $ Text.lines s + + +fieldLines :: Maybe a -> (a -> [Text]) -> [Text] +fieldLines a f = maybe [] (([""] <>) . f) a + + +fieldLine :: Maybe a -> (a -> Text) -> [Text] +fieldLine a f = maybe [] (\b -> ["", f b]) a + + +printLog :: String -> IO () +printLog message = hPutStrLn stderr $ "Setup.hs: " ++ message diff --git a/semantic-conventions/hs-opentelemetry-semantic-conventions.cabal b/semantic-conventions/hs-opentelemetry-semantic-conventions.cabal new file mode 100644 index 00000000..13220f5e --- /dev/null +++ b/semantic-conventions/hs-opentelemetry-semantic-conventions.cabal @@ -0,0 +1,67 @@ +cabal-version: 2.4 + +name: hs-opentelemetry-semantic-conventions +version: 1.24.0.0 +author: Kazuki Okamoto (岡本和樹) +maintainer: kazuki.okamoto@herp.co.jp +synopsis: OpenTelemetry Semantic Conventions for Haskell +description: + OpenTelemetry Semantic Conventions for Haskell is a library that is automatically generated + based on [semantic-conventions](https://github.com/open-telemetry/semantic-conventions/) v1.24. + + This module's version A.B.X.Y means that A.B is the version of the original semantic-conventions, + and X.Y is the version of this module. + +common common + build-depends: base >= 4 && < 5 + ghc-options: -Wall + if impl(ghc >= 8.0) + ghc-options: -Wcompat + default-language: Haskell2010 + +custom-setup + setup-depends: aeson >= 2.0, + base, + Cabal, + Glob, + directory, + filepath, + yaml, + text, + vector + +library + import: common + hs-source-dirs: gen + exposed-modules: OpenTelemetry.SemanticConventions + autogen-modules: OpenTelemetry.SemanticConventions + build-depends: hs-opentelemetry-api, + text, + ghc-options: -Wno-name-shadowing + if impl(ghc >= 6.4) + ghc-options: -Wincomplete-record-updates + if impl(ghc >= 6.8) + ghc-options: -Wmonomorphism-restriction + if impl(ghc >= 7.0) + ghc-options: -Wmissing-import-lists + if impl(ghc >= 7.2) + ghc-options: -Wincomplete-uni-patterns + -Widentities + if impl(ghc >= 8.0) + ghc-options: -Wmissing-exported-signatures + -Wredundant-constraints + if impl(ghc >= 8.2) + ghc-options: -Wmissing-home-modules + if impl(ghc >= 8.4) + ghc-options: -Wmissing-export-lists + -Wpartial-fields + if impl(ghc >= 8.8) + ghc-options: -Wmissing-deriving-strategies + if impl(ghc >= 8.10) + ghc-options: -Wunused-packages + if impl(ghc >= 9.0) + ghc-options: -Winvalid-haddock + if impl(ghc >= 9.2) + ghc-options: -Wmissing-kind-signatures + -Woperator-whitespace + -Wredundant-bang-patterns diff --git a/semantic-conventions/model b/semantic-conventions/model new file mode 160000 index 00000000..44690f11 --- /dev/null +++ b/semantic-conventions/model @@ -0,0 +1 @@ +Subproject commit 44690f11c7edf9b916f8486f9a4440b841312cb0 diff --git a/stack-ghc-8.10.yaml b/stack-ghc-8.10.yaml deleted file mode 100644 index 17660333..00000000 --- a/stack-ghc-8.10.yaml +++ /dev/null @@ -1,56 +0,0 @@ -resolver: lts-18.20 - -packages: -- api -- sdk -- otlp -# - examples/aws-s3 -# - examples/grpc-echo # only able to be built with cabal -- examples/hdbc-mysql -- examples/http-server -- examples/yesod-minimal -- examples/yesod-subsite -- exporters/handle -- exporters/in-memory -# - exporters/jaeger -- exporters/otlp -# - exporters/prometheus -# - instrumentation/amazonka -- instrumentation/cloudflare -- instrumentation/conduit -# - instrumentation/grpc-haskell # only able to be built with cabal -- instrumentation/hdbc -- instrumentation/hdbc-mysql -- instrumentation/hedis -# - instrumentation/herp-logger-datadog # 本家に PR しない -- instrumentation/hspec -- instrumentation/http-client -- instrumentation/persistent -- instrumentation/persistent-mysql -- instrumentation/postgresql-simple -- instrumentation/wai -- instrumentation/yesod -- propagators/b3 -- propagators/datadog -# - propagators/jaeger -- propagators/w3c -- utils/exceptions -- vendors/datadog - -extra-deps: -- hspec-2.11.7@sha256:2869580a2a29e7beb6268ea3dc561583f4ae229ed1f47fb1c92e8c09ce35acec,1763 -- hspec-core-2.11.7@sha256:90d8873356d7e15f843bc523360e206e8e356ff6b82a1fa4b3889dc31d073ea1,6814 -- hspec-discover-2.11.7@sha256:6307eb16d308258a99a242025df50217d835ba0a3f205b1202a100a175877b38,2169 -- hspec-expectations-0.8.4@sha256:4237f094a7931202ff57ac6475542b0b314b50a7024550e2b6eb87cfb0d4ff93,1702 -- persistent-2.13.3.0@sha256:89a4a286ec3739d452f67332a03a392aa57c3e97237b61efcd5b99d50aae9cfc,6762 -- persistent-postgresql-2.13.4.0@sha256:7fc0ffc4a591c0355c8ad793bc6de08c13321c81a3fb748c9a23448ac88d987a,3686 -- proto-lens-0.7.1.0@sha256:b151890929e71db5b8c2ad86cd758bcdf1dfcf25f34eb6c9ce19e3d7cd4eae39,2959 -- proto-lens-runtime-0.7.0.1@sha256:703f327422b2e204f8ea13c5e178edd8ab42ccd01c7a5a89fcb1b37ab474c68a,3038 -- thread-utils-context-0.2.0.0@sha256:7863e568c7a43cd21616342d20484d4c962aaa9710619f104c6fb7ee32273940,1883 -- thread-utils-finalizers-0.1.0.0@sha256:a8435240bfc0ae96c94704d2986699a11a395c496f9a7f2e5f5d729a0b967549,1381 -- github: ryantm/hdbc-mysql - commit: 80f8077b29ee27bce4141b385a8b28f42cbbbe46 # HEAD of master at 2023-12-19 - -nix: - enable: true - packages: [libffi, mysql80, openssl, pcre, postgresql, zlib, zstd] diff --git a/stack-ghc-8.10.yaml.lock b/stack-ghc-8.10.yaml.lock deleted file mode 100644 index 15b14520..00000000 --- a/stack-ghc-8.10.yaml.lock +++ /dev/null @@ -1,93 +0,0 @@ -# This file was autogenerated by Stack. -# You should not edit this file by hand. -# For more information, please see the documentation at: -# https://docs.haskellstack.org/en/stable/lock_files - -packages: -- completed: - hackage: hspec-2.11.7@sha256:2869580a2a29e7beb6268ea3dc561583f4ae229ed1f47fb1c92e8c09ce35acec,1763 - pantry-tree: - size: 584 - sha256: f241a7710ebee50583f9aebff61aaf4d36619ba7d6538b39b80ee4695c70552e - original: - hackage: hspec-2.11.7@sha256:2869580a2a29e7beb6268ea3dc561583f4ae229ed1f47fb1c92e8c09ce35acec,1763 -- completed: - hackage: hspec-core-2.11.7@sha256:90d8873356d7e15f843bc523360e206e8e356ff6b82a1fa4b3889dc31d073ea1,6814 - pantry-tree: - size: 6231 - sha256: 8db12c1f6965d9f0898f04d7b5f1d77682c8ab2d5c394c4a431229df7c4acb14 - original: - hackage: hspec-core-2.11.7@sha256:90d8873356d7e15f843bc523360e206e8e356ff6b82a1fa4b3889dc31d073ea1,6814 -- completed: - hackage: hspec-discover-2.11.7@sha256:6307eb16d308258a99a242025df50217d835ba0a3f205b1202a100a175877b38,2169 - pantry-tree: - size: 829 - sha256: 141b4987d519ad1ca1114737f510f20adc2456bf44c040f41a63792f47d009eb - original: - hackage: hspec-discover-2.11.7@sha256:6307eb16d308258a99a242025df50217d835ba0a3f205b1202a100a175877b38,2169 -- completed: - hackage: hspec-expectations-0.8.4@sha256:4237f094a7931202ff57ac6475542b0b314b50a7024550e2b6eb87cfb0d4ff93,1702 - pantry-tree: - size: 741 - sha256: 87681840d430b84686f83f1ab8b5873b09c349775698665233443914acf9ba2b - original: - hackage: hspec-expectations-0.8.4@sha256:4237f094a7931202ff57ac6475542b0b314b50a7024550e2b6eb87cfb0d4ff93,1702 -- completed: - hackage: persistent-2.13.3.0@sha256:89a4a286ec3739d452f67332a03a392aa57c3e97237b61efcd5b99d50aae9cfc,6762 - pantry-tree: - size: 6052 - sha256: debd3496e44bf01264de8bc0d3da92991c1550632fe1ef66818392f4c9955323 - original: - hackage: persistent-2.13.3.0@sha256:89a4a286ec3739d452f67332a03a392aa57c3e97237b61efcd5b99d50aae9cfc,6762 -- completed: - hackage: persistent-postgresql-2.13.4.0@sha256:7fc0ffc4a591c0355c8ad793bc6de08c13321c81a3fb748c9a23448ac88d987a,3686 - pantry-tree: - size: 1140 - sha256: 78b6907bf9bc82a524251dfeb2cf0d3f8c599427c8ae0b0a1d933158b6909281 - original: - hackage: persistent-postgresql-2.13.4.0@sha256:7fc0ffc4a591c0355c8ad793bc6de08c13321c81a3fb748c9a23448ac88d987a,3686 -- completed: - hackage: proto-lens-0.7.1.0@sha256:b151890929e71db5b8c2ad86cd758bcdf1dfcf25f34eb6c9ce19e3d7cd4eae39,2959 - pantry-tree: - size: 1857 - sha256: 2f1199d04d0588805e06faa0bf9a75898584d76243d4f945acbcc0e93913732e - original: - hackage: proto-lens-0.7.1.0@sha256:b151890929e71db5b8c2ad86cd758bcdf1dfcf25f34eb6c9ce19e3d7cd4eae39,2959 -- completed: - hackage: proto-lens-runtime-0.7.0.1@sha256:703f327422b2e204f8ea13c5e178edd8ab42ccd01c7a5a89fcb1b37ab474c68a,3038 - pantry-tree: - size: 168 - sha256: 145cb9a15b73d45b07cb3f9f0716256b2ed9e27ac296268ce100a4f0e477e110 - original: - hackage: proto-lens-runtime-0.7.0.1@sha256:703f327422b2e204f8ea13c5e178edd8ab42ccd01c7a5a89fcb1b37ab474c68a,3038 -- completed: - hackage: thread-utils-context-0.2.0.0@sha256:7863e568c7a43cd21616342d20484d4c962aaa9710619f104c6fb7ee32273940,1883 - pantry-tree: - size: 450 - sha256: 605ea068880ad39c96fce0d91db9f2d54553ed43dfc41c37845fade8be2e9568 - original: - hackage: thread-utils-context-0.2.0.0@sha256:7863e568c7a43cd21616342d20484d4c962aaa9710619f104c6fb7ee32273940,1883 -- completed: - hackage: thread-utils-finalizers-0.1.0.0@sha256:a8435240bfc0ae96c94704d2986699a11a395c496f9a7f2e5f5d729a0b967549,1381 - pantry-tree: - size: 400 - sha256: 7f708d158d5d0e32ffe77f6375a792ceb6f92e4d8dd8b32fc69e7de962e7e518 - original: - hackage: thread-utils-finalizers-0.1.0.0@sha256:a8435240bfc0ae96c94704d2986699a11a395c496f9a7f2e5f5d729a0b967549,1381 -- completed: - size: 29580 - url: https://github.com/ryantm/hdbc-mysql/archive/80f8077b29ee27bce4141b385a8b28f42cbbbe46.tar.gz - name: HDBC-mysql - version: 1.0.0.0 - sha256: ca7ad707203e14368d09500bcb260902e23b445c1344d12f5911e9a9ea6c9043 - pantry-tree: - size: 1139 - sha256: fd3e0407e96f5610fee63c076428a03c0caf361f066099444f8b703da421bcb1 - original: - url: https://github.com/ryantm/hdbc-mysql/archive/80f8077b29ee27bce4141b385a8b28f42cbbbe46.tar.gz -snapshots: -- completed: - size: 586106 - url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/20.yaml - sha256: 8699812d2b2c1f83d6ad1261de9cf628ed36a1cfc14f19d67188e005e7a3a39d - original: lts-18.20 diff --git a/stack-ghc-9.2.yaml b/stack-ghc-9.2.yaml index 87b34751..520d7390 100644 --- a/stack-ghc-9.2.yaml +++ b/stack-ghc-9.2.yaml @@ -4,6 +4,7 @@ packages: - api - sdk - otlp +- semantic-conventions - examples/aws-s3 # - examples/grpc-echo # only able to be built with cabal - examples/hdbc-mysql diff --git a/stack.yaml b/stack.yaml index 387cc1e4..6013b804 100644 --- a/stack.yaml +++ b/stack.yaml @@ -4,6 +4,7 @@ packages: - api - sdk - otlp +- semantic-conventions - examples/aws-s3 # - examples/grpc-echo # only able to be built with cabal - examples/hdbc-mysql