feat(exporter-logs-otlp-proto): implements protobuf exporter for logs (#3779)
Co-authored-by: Marc Pichler <marc.pichler@dynatrace.com>
This commit is contained in:
parent
05bcd822a9
commit
1fc4ac652f
|
@ -19,6 +19,7 @@ All notable changes to experimental packages in this project will be documented
|
|||
* feat(otlp-trace-exporters): Add User-Agent header to OTLP trace exporters. [#3790](https://github.com/open-telemetry/opentelemetry-js/pull/3790) @JamieDanielson
|
||||
* feat(otlp-metric-exporters): Add User-Agent header to OTLP metric exporters. [#3806](https://github.com/open-telemetry/opentelemetry-js/pull/3806) @JamieDanielson
|
||||
* feat(opencensus-shim): add OpenCensus trace shim [#3809](https://github.com/open-telemetry/opentelemetry-js/pull/3809) @aabmass
|
||||
* feat(exporter-logs-otlp-proto): protobuf exporter for logs. [#3779](https://github.com/open-telemetry/opentelemetry-js/pull/3779) @Abinet18
|
||||
|
||||
### :bug: (Bug Fix)
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
build
|
|
@ -0,0 +1,8 @@
|
|||
module.exports = {
|
||||
"env": {
|
||||
"mocha": true,
|
||||
"commonjs": true,
|
||||
"node": true,
|
||||
},
|
||||
...require('../../../eslint.config.js')
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
/bin
|
||||
/coverage
|
||||
/doc
|
||||
/test
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -0,0 +1,110 @@
|
|||
# An OTLP exporter to send logs using protobuf over HTTP
|
||||
|
||||
[![NPM Published Version][npm-img]][npm-url]
|
||||
[![Apache License][license-image]][license-image]
|
||||
|
||||
**Note: This is an experimental package under active development. New releases may include breaking changes.**
|
||||
|
||||
This module provides an exporter for OTLP (http/protobuf) logs using protocol version `v0.18`.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npm install --save @opentelemetry/exporter-logs-otlp-proto
|
||||
```
|
||||
|
||||
## Further Documentation
|
||||
|
||||
To see documentation and sample code for the traces exporter, as well as instructions for using TLS, see the [exporter-trace-otlp-proto package][trace-exporter-url].
|
||||
To see documentation and sample code for the metric exporter, see the [exporter-trace-otlp-proto package][metrics-exporter-url].
|
||||
|
||||
## Example Setup
|
||||
|
||||
```js
|
||||
const { LoggerProvider, SimpleLogRecordProcessor } = require('@opentelemetry/sdk-logs');
|
||||
const { OTLPLogsExporter } = require('@opentelemetry/exporter-logs-otlp-proto');
|
||||
|
||||
const collectorOptions = {
|
||||
url: '<opentelemetry-collector-url>', // url is optional and can be omitted - default is http://localhost:4318/v1/logs
|
||||
headers: {
|
||||
foo: 'bar'
|
||||
}, //an optional object containing custom headers to be sent with each request will only work with http
|
||||
};
|
||||
|
||||
const logProvider = new LoggerProvider({resource: new Resource({'service.name': 'testApp'})});
|
||||
const logExporter = new OTLPLogsExporter(collectorOptions);
|
||||
logProvider.addLogRecordProcessor(new SimpleLogRecordProcessor(exporter));
|
||||
|
||||
const logger = logProvider.getLogger('test_log_instrumentation');
|
||||
|
||||
logger.emit({
|
||||
//log data to emit
|
||||
})
|
||||
```
|
||||
|
||||
## Exporter Timeout Configuration
|
||||
|
||||
The OTLPLogsExporter has a timeout configuration option which is the maximum time, in milliseconds, the OTLP exporter will wait for each batch export. The default value is 10000ms.
|
||||
|
||||
To override the default timeout duration, use the following options:
|
||||
|
||||
+ Set with environment variables:
|
||||
|
||||
| Environment variable | Description |
|
||||
------------------------------|----------------------|-------------|
|
||||
| OTEL_EXPORTER_OTLP_LOGS_TIMEOUT | The maximum waiting time, in milliseconds, allowed to send each OTLP trace batch. Default is 10000. |
|
||||
| OTEL_EXPORTER_OTLP_TIMEOUT | The maximum waiting time, in milliseconds, allowed to send each OTLP trace and metric batch. Default is 10000. |
|
||||
|
||||
> `OTEL_EXPORTER_OTLP_LOGS_TIMEOUT` takes precedence and overrides `OTEL_EXPORTER_OTLP_TIMEOUT`.
|
||||
|
||||
+ Provide `timeoutMillis` to OTLPLogsExporter with `collectorOptions`:
|
||||
|
||||
```js
|
||||
const collectorOptions = {
|
||||
timeoutMillis: 15000,
|
||||
url: '<opentelemetry-collector-url>', // url is optional and can be omitted - default is http://localhost:4318/v1/logs
|
||||
headers: {
|
||||
foo: 'bar'
|
||||
}, //an optional object containing custom headers to be sent with each request will only work with http
|
||||
};
|
||||
|
||||
const exporter = new OTLPLogsExporter(collectorOptions);
|
||||
```
|
||||
|
||||
> Providing `timeoutMillis` with `collectorOptions` takes precedence and overrides timeout set with environment variables.
|
||||
|
||||
## OTLP Exporter Retry
|
||||
|
||||
OTLP requires that transient errors be handled with a [retry strategy](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#retry).
|
||||
|
||||
This retry policy has the following configuration, which there is currently no way to customize.
|
||||
|
||||
+ `DEFAULT_EXPORT_MAX_ATTEMPTS`: The maximum number of attempts, including the original request. Defaults to 5.
|
||||
+ `DEFAULT_EXPORT_INITIAL_BACKOFF`: The initial backoff duration. Defaults to 1 second.
|
||||
+ `DEFAULT_EXPORT_MAX_BACKOFF`: The maximum backoff duration. Defaults to 5 seconds.
|
||||
+ `DEFAULT_EXPORT_BACKOFF_MULTIPLIER`: The backoff multiplier. Defaults to 1.5.
|
||||
|
||||
This retry policy first checks if the response has a `'Retry-After'` header. If there is a `'Retry-After'` header, the exporter will wait the amount specified in the `'Retry-After'` header before retrying. If there is no `'Retry-After'` header, the exporter will use an exponential backoff with jitter retry strategy.
|
||||
|
||||
> The exporter will retry exporting within the [exporter timeout configuration](#Exporter-Timeout-Configuration) time.
|
||||
|
||||
## Useful links
|
||||
|
||||
+ For more information on OpenTelemetry, visit: <https://opentelemetry.io/>
|
||||
+ For more about OpenTelemetry JavaScript: <https://github.com/open-telemetry/opentelemetry-js>
|
||||
+ For help or feedback on this project, join us in [GitHub Discussions][discussions-url]
|
||||
|
||||
## License
|
||||
|
||||
Apache 2.0 - See [LICENSE][license-url] for more information.
|
||||
|
||||
[discussions-url]: https://github.com/open-telemetry/opentelemetry-js/discussions
|
||||
[license-url]: https://github.com/open-telemetry/opentelemetry-js/blob/main/LICENSE
|
||||
[license-image]: https://img.shields.io/badge/license-Apache_2.0-green.svg?style=flat
|
||||
[npm-url]: https://www.npmjs.com/package/@opentelemetry/exporter-logs-otlp-proto
|
||||
[npm-img]: https://badge.fury.io/js/%40opentelemetry%2Fexporter-logs-otlp-proto.svg
|
||||
[opentelemetry-collector-url]: https://github.com/open-telemetry/opentelemetry-collector
|
||||
[semconv-resource-service-name]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/semantic_conventions/README.md#service
|
||||
[logs-exporter-url]: https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-logs-otlp-proto
|
||||
[trace-exporter-url]: https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/exporter-trace-otlp-proto
|
||||
[metrics-exporter-url]: https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-exporter-metrics-otlp-proto
|
|
@ -0,0 +1,26 @@
|
|||
/*!
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const karmaWebpackConfig = require('../../../karma.webpack');
|
||||
const karmaBaseConfig = require('../../../karma.base');
|
||||
|
||||
module.exports = (config) => {
|
||||
config.set(Object.assign({}, karmaBaseConfig, {
|
||||
webpack: karmaWebpackConfig,
|
||||
files: ['test/browser/index-webpack.ts'],
|
||||
preprocessors: { 'test/browser/index-webpack.ts': ['webpack'] }
|
||||
}))
|
||||
};
|
|
@ -0,0 +1,95 @@
|
|||
{
|
||||
"name": "@opentelemetry/exporter-logs-otlp-proto",
|
||||
"version": "0.39.1",
|
||||
"description": "An OTLP exporter to send logs using protobuf over HTTP",
|
||||
"main": "build/src/index.js",
|
||||
"module": "build/esm/index.js",
|
||||
"esnext": "build/esnext/index.js",
|
||||
"types": "build/src/index.d.ts",
|
||||
"repository": "open-telemetry/opentelemetry-js",
|
||||
"browser": {
|
||||
"./src/platform/index.ts": "./src/platform/browser/index.ts",
|
||||
"./build/esm/platform/index.js": "./build/esm/platform/browser/index.js",
|
||||
"./build/esnext/platform/index.js": "./build/esnext/platform/browser/index.js",
|
||||
"./build/src/platform/index.js": "./build/src/platform/browser/index.js"
|
||||
},
|
||||
"scripts": {
|
||||
"prepublishOnly": "npm run compile",
|
||||
"compile": "tsc --build tsconfig.json tsconfig.esm.json tsconfig.esnext.json",
|
||||
"clean": "tsc --build --clean tsconfig.json tsconfig.esm.json tsconfig.esnext.json",
|
||||
"lint": "eslint . --ext .ts",
|
||||
"lint:fix": "eslint . --ext .ts --fix",
|
||||
"tdd": "npm run test -- --watch-extensions ts --watch",
|
||||
"test": "nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts' --exclude 'test/browser/**/*.ts'",
|
||||
"test:browser": "nyc karma start --single-run",
|
||||
"version": "node ../../../scripts/version-update.js",
|
||||
"watch": "tsc --build --watch tsconfig.json tsconfig.esm.json tsconfig.esnext.json",
|
||||
"precompile": "lerna run version --scope $(npm pkg get name) --include-dependencies",
|
||||
"prewatch": "npm run precompile",
|
||||
"peer-api-check": "node ../../../scripts/peer-api-check.js",
|
||||
"codecov": "nyc report --reporter=json && codecov -f coverage/*.json -p ../../../"
|
||||
},
|
||||
"keywords": [
|
||||
"opentelemetry",
|
||||
"nodejs",
|
||||
"protobuf",
|
||||
"tracing",
|
||||
"profiling",
|
||||
"metrics",
|
||||
"stats",
|
||||
"logs"
|
||||
],
|
||||
"author": "OpenTelemetry Authors",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"files": [
|
||||
"build/esm/**/*.js",
|
||||
"build/esm/**/*.js.map",
|
||||
"build/esm/**/*.d.ts",
|
||||
"build/esnext/**/*.js",
|
||||
"build/esnext/**/*.js.map",
|
||||
"build/esnext/**/*.d.ts",
|
||||
"build/src/**/*.js",
|
||||
"build/src/**/*.js.map",
|
||||
"build/src/**/*.d.ts",
|
||||
"build/protos/**/*.proto",
|
||||
"doc",
|
||||
"LICENSE",
|
||||
"README.md"
|
||||
],
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.16.0",
|
||||
"@opentelemetry/api": "1.4.1",
|
||||
"@types/mocha": "10.0.0",
|
||||
"@types/node": "18.6.5",
|
||||
"@types/sinon": "10.0.13",
|
||||
"codecov": "3.8.3",
|
||||
"cpx": "1.5.0",
|
||||
"mocha": "10.0.0",
|
||||
"nyc": "15.1.0",
|
||||
"sinon": "15.0.0",
|
||||
"ts-loader": "8.4.0",
|
||||
"ts-mocha": "10.0.0",
|
||||
"typescript": "4.4.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@opentelemetry/api": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@opentelemetry/core": "1.13.0",
|
||||
"@opentelemetry/otlp-transformer": "0.39.1",
|
||||
"@opentelemetry/resources": "1.13.0",
|
||||
"@opentelemetry/sdk-trace-base": "1.13.0",
|
||||
"@opentelemetry/api-logs": "^0.39.1",
|
||||
"@opentelemetry/otlp-exporter-base": "0.39.1",
|
||||
"@opentelemetry/otlp-proto-exporter-base": "0.39.1",
|
||||
"@opentelemetry/sdk-logs": "^0.39.1"
|
||||
},
|
||||
"homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/exporter-logs-otlp-proto",
|
||||
"sideEffects": false
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export { OTLPLogsExporter } from './platform';
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { getEnv, baggageUtils } from '@opentelemetry/core';
|
||||
import {
|
||||
OTLPExporterConfigBase,
|
||||
appendResourcePathToUrl,
|
||||
appendRootPathToUrlIfNeeded,
|
||||
} from '@opentelemetry/otlp-exporter-base';
|
||||
import {
|
||||
OTLPProtoExporterBrowserBase,
|
||||
ServiceClientType,
|
||||
} from '@opentelemetry/otlp-proto-exporter-base';
|
||||
import {
|
||||
createExportLogsServiceRequest,
|
||||
IExportLogsServiceRequest,
|
||||
} from '@opentelemetry/otlp-transformer';
|
||||
|
||||
import { ReadableLogRecord, LogRecordExporter } from '@opentelemetry/sdk-logs';
|
||||
|
||||
const DEFAULT_COLLECTOR_RESOURCE_PATH = 'v1/logs';
|
||||
const DEFAULT_COLLECTOR_URL = `http://localhost:4318/${DEFAULT_COLLECTOR_RESOURCE_PATH}`;
|
||||
|
||||
/**
|
||||
* Collector Trace Exporter for Web
|
||||
*/
|
||||
export class OTLPLogsExporter
|
||||
extends OTLPProtoExporterBrowserBase<
|
||||
ReadableLogRecord,
|
||||
IExportLogsServiceRequest
|
||||
>
|
||||
implements LogRecordExporter
|
||||
{
|
||||
constructor(config: OTLPExporterConfigBase = {}) {
|
||||
super(config);
|
||||
this._headers = Object.assign(
|
||||
this._headers,
|
||||
baggageUtils.parseKeyPairsIntoRecord(
|
||||
getEnv().OTEL_EXPORTER_OTLP_LOGS_HEADERS
|
||||
)
|
||||
);
|
||||
}
|
||||
convert(logs: ReadableLogRecord[]): IExportLogsServiceRequest {
|
||||
return createExportLogsServiceRequest(logs);
|
||||
}
|
||||
|
||||
getDefaultUrl(config: OTLPExporterConfigBase): string {
|
||||
return typeof config.url === 'string'
|
||||
? config.url
|
||||
: getEnv().OTEL_EXPORTER_OTLP_LOGS_ENDPOINT.length > 0
|
||||
? appendRootPathToUrlIfNeeded(getEnv().OTEL_EXPORTER_OTLP_LOGS_ENDPOINT)
|
||||
: getEnv().OTEL_EXPORTER_OTLP_ENDPOINT.length > 0
|
||||
? appendResourcePathToUrl(
|
||||
getEnv().OTEL_EXPORTER_OTLP_ENDPOINT,
|
||||
DEFAULT_COLLECTOR_RESOURCE_PATH
|
||||
)
|
||||
: DEFAULT_COLLECTOR_URL;
|
||||
}
|
||||
|
||||
getServiceClientType() {
|
||||
return ServiceClientType.LOGS;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export { OTLPLogsExporter } from './OTLPLogsExporter';
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export { OTLPLogsExporter } from './node';
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { getEnv, baggageUtils } from '@opentelemetry/core';
|
||||
import {
|
||||
OTLPExporterConfigBase,
|
||||
appendResourcePathToUrl,
|
||||
appendRootPathToUrlIfNeeded,
|
||||
} from '@opentelemetry/otlp-exporter-base';
|
||||
import {
|
||||
OTLPProtoExporterNodeBase,
|
||||
ServiceClientType,
|
||||
} from '@opentelemetry/otlp-proto-exporter-base';
|
||||
import {
|
||||
createExportLogsServiceRequest,
|
||||
IExportLogsServiceRequest,
|
||||
} from '@opentelemetry/otlp-transformer';
|
||||
|
||||
import { ReadableLogRecord, LogRecordExporter } from '@opentelemetry/sdk-logs';
|
||||
|
||||
const DEFAULT_COLLECTOR_RESOURCE_PATH = 'v1/logs';
|
||||
const DEFAULT_COLLECTOR_URL = `http://localhost:4318/${DEFAULT_COLLECTOR_RESOURCE_PATH}`;
|
||||
|
||||
/**
|
||||
* Collector Trace Exporter for Node
|
||||
*/
|
||||
export class OTLPLogsExporter
|
||||
extends OTLPProtoExporterNodeBase<
|
||||
ReadableLogRecord,
|
||||
IExportLogsServiceRequest
|
||||
>
|
||||
implements LogRecordExporter
|
||||
{
|
||||
constructor(config: OTLPExporterConfigBase = {}) {
|
||||
super(config);
|
||||
this.headers = Object.assign(
|
||||
this.headers,
|
||||
baggageUtils.parseKeyPairsIntoRecord(
|
||||
getEnv().OTEL_EXPORTER_OTLP_LOGS_HEADERS
|
||||
)
|
||||
);
|
||||
}
|
||||
convert(logs: ReadableLogRecord[]): IExportLogsServiceRequest {
|
||||
return createExportLogsServiceRequest(logs);
|
||||
}
|
||||
|
||||
getDefaultUrl(config: OTLPExporterConfigBase): string {
|
||||
return typeof config.url === 'string'
|
||||
? config.url
|
||||
: getEnv().OTEL_EXPORTER_OTLP_LOGS_ENDPOINT.length > 0
|
||||
? appendRootPathToUrlIfNeeded(getEnv().OTEL_EXPORTER_OTLP_LOGS_ENDPOINT)
|
||||
: getEnv().OTEL_EXPORTER_OTLP_ENDPOINT.length > 0
|
||||
? appendResourcePathToUrl(
|
||||
getEnv().OTEL_EXPORTER_OTLP_ENDPOINT,
|
||||
DEFAULT_COLLECTOR_RESOURCE_PATH
|
||||
)
|
||||
: DEFAULT_COLLECTOR_URL;
|
||||
}
|
||||
|
||||
getServiceClientType() {
|
||||
return ServiceClientType.LOGS;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { OTLPLogsExporter } from './OTLPLogsExporter';
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as sinon from 'sinon';
|
||||
import { OTLPLogsExporter } from '../../src/platform/browser/index';
|
||||
|
||||
describe('OTLPLogsExporter - web', () => {
|
||||
let collectorLogsExporter: OTLPLogsExporter;
|
||||
describe('constructor', () => {
|
||||
let onInitSpy: any;
|
||||
beforeEach(() => {
|
||||
onInitSpy = sinon.stub(OTLPLogsExporter.prototype, 'onInit');
|
||||
const collectorExporterConfig = {
|
||||
hostname: 'foo',
|
||||
url: 'http://foo.bar.com',
|
||||
};
|
||||
collectorLogsExporter = new OTLPLogsExporter(collectorExporterConfig);
|
||||
});
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
});
|
||||
it('should create an instance', () => {
|
||||
assert.ok(typeof collectorLogsExporter !== 'undefined');
|
||||
});
|
||||
it('should call onInit', () => {
|
||||
assert.strictEqual(onInitSpy.callCount, 1);
|
||||
});
|
||||
it('should set hostname', () => {
|
||||
assert.strictEqual(collectorLogsExporter.hostname, 'foo');
|
||||
});
|
||||
|
||||
it('should set url', () => {
|
||||
assert.strictEqual(collectorLogsExporter.url, 'http://foo.bar.com');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
const testsContext = require.context('../browser', true, /test$/);
|
||||
testsContext.keys().forEach(testsContext);
|
||||
|
||||
const srcContext = require.context('.', true, /src$/);
|
||||
srcContext.keys().forEach(srcContext);
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { HrTime, TraceFlags } from '@opentelemetry/api';
|
||||
import { SeverityNumber } from '@opentelemetry/api-logs';
|
||||
import { Resource } from '@opentelemetry/resources';
|
||||
import * as assert from 'assert';
|
||||
import { VERSION } from '@opentelemetry/core';
|
||||
import {
|
||||
IAnyValue,
|
||||
IExportLogsServiceRequest,
|
||||
IKeyValue,
|
||||
ILogRecord,
|
||||
IResource,
|
||||
} from '@opentelemetry/otlp-transformer';
|
||||
import { ReadableLogRecord } from '@opentelemetry/sdk-logs';
|
||||
import { Stream } from 'stream';
|
||||
|
||||
export const mockedReadableLogRecord: ReadableLogRecord = {
|
||||
resource: Resource.default().merge(
|
||||
new Resource({
|
||||
'resource-attribute': 'some resource-attr value',
|
||||
})
|
||||
),
|
||||
instrumentationScope: {
|
||||
name: 'scope_name_1',
|
||||
version: '0.1.0',
|
||||
schemaUrl: 'http://url.to.schema',
|
||||
},
|
||||
hrTime: [1680253513, 123241635] as HrTime,
|
||||
hrTimeObserved: [1680253513, 123241635] as HrTime,
|
||||
attributes: {
|
||||
'some-attribute': 'some attribute value',
|
||||
},
|
||||
severityNumber: SeverityNumber.ERROR,
|
||||
severityText: 'error',
|
||||
body: 'some_log_body',
|
||||
spanContext: {
|
||||
traceFlags: TraceFlags.SAMPLED,
|
||||
traceId: '1f1008dc8e270e85c40a0d7c3939b278',
|
||||
spanId: '5e107261f64fa53e',
|
||||
},
|
||||
};
|
||||
export function ensureExportedAttributesAreCorrect(attributes: IKeyValue[]) {
|
||||
assert.deepStrictEqual(
|
||||
attributes,
|
||||
[
|
||||
{
|
||||
key: 'some-attribute',
|
||||
value: {
|
||||
stringValue: 'some attribute value',
|
||||
},
|
||||
},
|
||||
],
|
||||
'exported attributes are incorrect'
|
||||
);
|
||||
}
|
||||
|
||||
export function ensureExportedBodyIsCorrect(body?: IAnyValue) {
|
||||
assert.deepStrictEqual(
|
||||
body,
|
||||
{ stringValue: 'some_log_body' },
|
||||
'exported attributes are incorrect'
|
||||
);
|
||||
}
|
||||
|
||||
export function ensureExportedLogRecordIsCorrect(logRecord: ILogRecord) {
|
||||
ensureExportedBodyIsCorrect(logRecord.body);
|
||||
ensureExportedAttributesAreCorrect(logRecord.attributes);
|
||||
assert.strictEqual(
|
||||
logRecord.timeUnixNano,
|
||||
'1680253513123241728',
|
||||
'timeUnixNano is wrong'
|
||||
);
|
||||
assert.strictEqual(
|
||||
logRecord.observedTimeUnixNano,
|
||||
'1680253513123241728',
|
||||
'observedTimeUnixNano is wrong'
|
||||
);
|
||||
assert.strictEqual(
|
||||
logRecord.severityNumber,
|
||||
'SEVERITY_NUMBER_ERROR',
|
||||
'severityNumber is wrong'
|
||||
);
|
||||
assert.strictEqual(logRecord.severityText, 'error', 'severityText is wrong');
|
||||
assert.strictEqual(
|
||||
logRecord.droppedAttributesCount,
|
||||
0,
|
||||
'droppedAttributesCount is wrong'
|
||||
);
|
||||
assert.strictEqual(logRecord.flags, TraceFlags.SAMPLED, 'flags is wrong');
|
||||
}
|
||||
|
||||
export function ensureResourceIsCorrect(resource: IResource) {
|
||||
assert.deepStrictEqual(resource, {
|
||||
attributes: [
|
||||
{
|
||||
key: 'service.name',
|
||||
value: {
|
||||
stringValue: `unknown_service:${process.argv0}`,
|
||||
value: 'stringValue',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'telemetry.sdk.language',
|
||||
value: {
|
||||
stringValue: 'nodejs',
|
||||
value: 'stringValue',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'telemetry.sdk.name',
|
||||
value: {
|
||||
stringValue: 'opentelemetry',
|
||||
value: 'stringValue',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'telemetry.sdk.version',
|
||||
value: {
|
||||
stringValue: VERSION,
|
||||
value: 'stringValue',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'resource-attribute',
|
||||
value: {
|
||||
stringValue: 'some resource-attr value',
|
||||
value: 'stringValue',
|
||||
},
|
||||
},
|
||||
],
|
||||
droppedAttributesCount: 0,
|
||||
});
|
||||
}
|
||||
|
||||
export function ensureExportLogsServiceRequestIsSet(
|
||||
json: IExportLogsServiceRequest
|
||||
) {
|
||||
const resourceLogs = json.resourceLogs;
|
||||
assert.strictEqual(resourceLogs?.length, 1, 'resourceLogs is missing');
|
||||
|
||||
const resource = resourceLogs?.[0].resource;
|
||||
assert.ok(resource, 'resource is missing');
|
||||
|
||||
const scopeLogs = resourceLogs?.[0].scopeLogs;
|
||||
assert.strictEqual(scopeLogs?.length, 1, 'scopeLogs is missing');
|
||||
|
||||
const scope = scopeLogs?.[0].scope;
|
||||
assert.ok(scope, 'scope is missing');
|
||||
|
||||
const logRecords = scopeLogs?.[0].logRecords;
|
||||
assert.strictEqual(logRecords?.length, 1, 'logs are missing');
|
||||
}
|
||||
|
||||
export class MockedResponse extends Stream {
|
||||
constructor(private _code: number, private _msg?: string) {
|
||||
super();
|
||||
}
|
||||
|
||||
send(data: string) {
|
||||
this.emit('data', data);
|
||||
this.emit('end');
|
||||
}
|
||||
|
||||
get statusCode() {
|
||||
return this._code;
|
||||
}
|
||||
|
||||
get statusMessage() {
|
||||
return this._msg;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,416 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { diag } from '@opentelemetry/api';
|
||||
import { ExportResultCode } from '@opentelemetry/core';
|
||||
import * as assert from 'assert';
|
||||
import * as http from 'http';
|
||||
import * as sinon from 'sinon';
|
||||
import { Stream, PassThrough } from 'stream';
|
||||
import * as zlib from 'zlib';
|
||||
import { OTLPLogsExporter } from '../../src';
|
||||
import {
|
||||
ensureExportLogsServiceRequestIsSet,
|
||||
ensureExportedLogRecordIsCorrect,
|
||||
mockedReadableLogRecord,
|
||||
MockedResponse,
|
||||
} from '../logHelper';
|
||||
import {
|
||||
CompressionAlgorithm,
|
||||
OTLPExporterNodeConfigBase,
|
||||
OTLPExporterError,
|
||||
} from '@opentelemetry/otlp-exporter-base';
|
||||
import {
|
||||
getExportRequestProto,
|
||||
ServiceClientType,
|
||||
} from '@opentelemetry/otlp-proto-exporter-base';
|
||||
import { IExportLogsServiceRequest } from '@opentelemetry/otlp-transformer';
|
||||
import { ReadableLogRecord } from '@opentelemetry/sdk-logs';
|
||||
|
||||
let fakeRequest: PassThrough;
|
||||
|
||||
describe('OTLPLogsExporter - node with proto over http', () => {
|
||||
let collectorExporter: OTLPLogsExporter;
|
||||
let collectorExporterConfig: OTLPExporterNodeConfigBase;
|
||||
let logs: ReadableLogRecord[];
|
||||
|
||||
afterEach(() => {
|
||||
fakeRequest = new Stream.PassThrough();
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
describe('when configuring via environment', () => {
|
||||
const envSource = process.env;
|
||||
it('should use url defined in env that ends with root path and append version and signal path', () => {
|
||||
envSource.OTEL_EXPORTER_OTLP_ENDPOINT = 'http://foo.bar/';
|
||||
const collectorExporter = new OTLPLogsExporter();
|
||||
assert.strictEqual(
|
||||
collectorExporter.url,
|
||||
`${envSource.OTEL_EXPORTER_OTLP_ENDPOINT}v1/logs`
|
||||
);
|
||||
envSource.OTEL_EXPORTER_OTLP_ENDPOINT = '';
|
||||
});
|
||||
it('should use url defined in env without checking if path is already present', () => {
|
||||
envSource.OTEL_EXPORTER_OTLP_ENDPOINT = 'http://foo.bar/v1/logs';
|
||||
const collectorExporter = new OTLPLogsExporter();
|
||||
assert.strictEqual(
|
||||
collectorExporter.url,
|
||||
`${envSource.OTEL_EXPORTER_OTLP_ENDPOINT}/v1/logs`
|
||||
);
|
||||
envSource.OTEL_EXPORTER_OTLP_ENDPOINT = '';
|
||||
});
|
||||
it('should use url defined in env and append version and signal', () => {
|
||||
envSource.OTEL_EXPORTER_OTLP_ENDPOINT = 'http://foo.bar';
|
||||
const collectorExporter = new OTLPLogsExporter();
|
||||
assert.strictEqual(
|
||||
collectorExporter.url,
|
||||
`${envSource.OTEL_EXPORTER_OTLP_ENDPOINT}/v1/logs`
|
||||
);
|
||||
envSource.OTEL_EXPORTER_OTLP_ENDPOINT = '';
|
||||
});
|
||||
it('should override global exporter url with signal url defined in env', () => {
|
||||
envSource.OTEL_EXPORTER_OTLP_ENDPOINT = 'http://foo.bar/';
|
||||
envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = 'http://foo.logs/';
|
||||
const collectorExporter = new OTLPLogsExporter();
|
||||
assert.strictEqual(
|
||||
collectorExporter.url,
|
||||
envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT
|
||||
);
|
||||
envSource.OTEL_EXPORTER_OTLP_ENDPOINT = '';
|
||||
envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = '';
|
||||
});
|
||||
it('should add root path when signal url defined in env contains no path and no root path', () => {
|
||||
envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = 'http://foo.bar';
|
||||
const collectorExporter = new OTLPLogsExporter();
|
||||
assert.strictEqual(
|
||||
collectorExporter.url,
|
||||
`${envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT}/`
|
||||
);
|
||||
envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = '';
|
||||
});
|
||||
it('should not add root path when signal url defined in env contains root path but no path', () => {
|
||||
envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = 'http://foo.bar/';
|
||||
const collectorExporter = new OTLPLogsExporter();
|
||||
assert.strictEqual(
|
||||
collectorExporter.url,
|
||||
`${envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT}`
|
||||
);
|
||||
envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = '';
|
||||
});
|
||||
it('should not add root path when signal url defined in env contains path', () => {
|
||||
envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = 'http://foo.bar/v1/logs';
|
||||
const collectorExporter = new OTLPLogsExporter();
|
||||
assert.strictEqual(
|
||||
collectorExporter.url,
|
||||
`${envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT}`
|
||||
);
|
||||
envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = '';
|
||||
});
|
||||
it('should not add root path when signal url defined in env contains path and ends in /', () => {
|
||||
envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = 'http://foo.bar/v1/logs/';
|
||||
const collectorExporter = new OTLPLogsExporter();
|
||||
assert.strictEqual(
|
||||
collectorExporter.url,
|
||||
`${envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT}`
|
||||
);
|
||||
envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = '';
|
||||
});
|
||||
it('should use headers defined via env', () => {
|
||||
envSource.OTEL_EXPORTER_OTLP_LOGS_HEADERS = 'foo=bar';
|
||||
const collectorExporter = new OTLPLogsExporter();
|
||||
assert.strictEqual(collectorExporter.headers.foo, 'bar');
|
||||
envSource.OTEL_EXPORTER_OTLP_HEADERS = '';
|
||||
});
|
||||
it('should override global headers config with signal headers defined via env', () => {
|
||||
envSource.OTEL_EXPORTER_OTLP_HEADERS = 'foo=bar,bar=foo';
|
||||
envSource.OTEL_EXPORTER_OTLP_LOGS_HEADERS = 'foo=boo';
|
||||
const collectorExporter = new OTLPLogsExporter();
|
||||
assert.strictEqual(collectorExporter.headers.foo, 'boo');
|
||||
assert.strictEqual(collectorExporter.headers.bar, 'foo');
|
||||
envSource.OTEL_EXPORTER_OTLP_LOGS_HEADERS = '';
|
||||
envSource.OTEL_EXPORTER_OTLP_HEADERS = '';
|
||||
});
|
||||
});
|
||||
|
||||
describe('export', () => {
|
||||
beforeEach(() => {
|
||||
collectorExporterConfig = {
|
||||
headers: {
|
||||
foo: 'bar',
|
||||
},
|
||||
hostname: 'foo',
|
||||
url: 'http://foo.bar.com',
|
||||
keepAlive: true,
|
||||
httpAgentOptions: { keepAliveMsecs: 2000 },
|
||||
};
|
||||
collectorExporter = new OTLPLogsExporter(collectorExporterConfig);
|
||||
logs = [];
|
||||
logs.push(Object.assign({}, mockedReadableLogRecord));
|
||||
});
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
it('should open the connection', done => {
|
||||
collectorExporter.export(logs, () => {});
|
||||
|
||||
sinon.stub(http, 'request').callsFake((options: any, cb: any) => {
|
||||
assert.strictEqual(options.hostname, 'foo.bar.com');
|
||||
assert.strictEqual(options.method, 'POST');
|
||||
assert.strictEqual(options.path, '/');
|
||||
|
||||
const mockRes = new MockedResponse(200);
|
||||
cb(mockRes);
|
||||
mockRes.send('success');
|
||||
done();
|
||||
return fakeRequest as any;
|
||||
});
|
||||
});
|
||||
|
||||
it('should set custom headers', done => {
|
||||
collectorExporter.export(logs, () => {});
|
||||
|
||||
sinon.stub(http, 'request').callsFake((options: any, cb: any) => {
|
||||
assert.strictEqual(options.headers['foo'], 'bar');
|
||||
|
||||
const mockRes = new MockedResponse(200);
|
||||
cb(mockRes);
|
||||
mockRes.send('success');
|
||||
done();
|
||||
return fakeRequest as any;
|
||||
});
|
||||
});
|
||||
|
||||
it('should have keep alive and keepAliveMsecs option set', done => {
|
||||
collectorExporter.export(logs, () => {});
|
||||
|
||||
sinon.stub(http, 'request').callsFake((options: any, cb: any) => {
|
||||
assert.strictEqual(options.agent.keepAlive, true);
|
||||
assert.strictEqual(options.agent.options.keepAliveMsecs, 2000);
|
||||
|
||||
const mockRes = new MockedResponse(200);
|
||||
cb(mockRes);
|
||||
mockRes.send('success');
|
||||
done();
|
||||
return fakeRequest as any;
|
||||
});
|
||||
});
|
||||
|
||||
it('should successfully send the logs', done => {
|
||||
const fakeRequest = new Stream.PassThrough();
|
||||
sinon.stub(http, 'request').returns(fakeRequest as any);
|
||||
|
||||
let buff = Buffer.from('');
|
||||
fakeRequest.on('end', () => {
|
||||
const ExportLogsServiceRequestProto = getExportRequestProto(
|
||||
ServiceClientType.LOGS
|
||||
);
|
||||
const data = ExportLogsServiceRequestProto.decode(buff);
|
||||
const json = data?.toJSON() as IExportLogsServiceRequest;
|
||||
const log1 = json.resourceLogs?.[0].scopeLogs?.[0].logRecords?.[0];
|
||||
assert.ok(typeof log1 !== 'undefined', "log doesn't exist");
|
||||
ensureExportedLogRecordIsCorrect(log1);
|
||||
|
||||
ensureExportLogsServiceRequestIsSet(json);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
fakeRequest.on('data', chunk => {
|
||||
buff = Buffer.concat([buff, chunk]);
|
||||
});
|
||||
|
||||
const clock = sinon.useFakeTimers();
|
||||
collectorExporter.export(logs, () => {});
|
||||
clock.tick(200);
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('should log the successful message', done => {
|
||||
// Need to stub/spy on the underlying logger as the "diag" instance is global
|
||||
const spyLoggerError = sinon.stub(diag, 'error');
|
||||
|
||||
collectorExporter.export(logs, result => {
|
||||
assert.strictEqual(result.code, ExportResultCode.SUCCESS);
|
||||
assert.strictEqual(spyLoggerError.args.length, 0);
|
||||
done();
|
||||
});
|
||||
|
||||
sinon.stub(http, 'request').callsFake((options: any, cb: any) => {
|
||||
const mockRes = new MockedResponse(200);
|
||||
cb(mockRes);
|
||||
mockRes.send('success');
|
||||
return fakeRequest as any;
|
||||
});
|
||||
});
|
||||
|
||||
it('should log the error message', done => {
|
||||
collectorExporter.export(logs, result => {
|
||||
assert.strictEqual(result.code, ExportResultCode.FAILED);
|
||||
// @ts-expect-error verify error code
|
||||
assert.strictEqual(result.error.code, 400);
|
||||
done();
|
||||
});
|
||||
|
||||
sinon.stub(http, 'request').callsFake((options: any, cb: any) => {
|
||||
const mockResError = new MockedResponse(400);
|
||||
cb(mockResError);
|
||||
mockResError.send('failed');
|
||||
|
||||
return fakeRequest as any;
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('export - with compression', () => {
|
||||
beforeEach(() => {
|
||||
collectorExporterConfig = {
|
||||
headers: {
|
||||
foo: 'bar',
|
||||
},
|
||||
hostname: 'foo',
|
||||
url: 'http://foo.bar.com',
|
||||
keepAlive: true,
|
||||
compression: CompressionAlgorithm.GZIP,
|
||||
httpAgentOptions: { keepAliveMsecs: 2000 },
|
||||
};
|
||||
collectorExporter = new OTLPLogsExporter(collectorExporterConfig);
|
||||
logs = [];
|
||||
logs.push(Object.assign({}, mockedReadableLogRecord));
|
||||
});
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
it('should successfully send the logs', done => {
|
||||
const fakeRequest = new Stream.PassThrough();
|
||||
sinon.stub(http, 'request').returns(fakeRequest as any);
|
||||
const spySetHeader = sinon.spy();
|
||||
(fakeRequest as any).setHeader = spySetHeader;
|
||||
|
||||
let buff = Buffer.from('');
|
||||
fakeRequest.on('end', () => {
|
||||
const unzippedBuff = zlib.gunzipSync(buff);
|
||||
const ExportLogsServiceRequestProto = getExportRequestProto(
|
||||
ServiceClientType.LOGS
|
||||
);
|
||||
const data = ExportLogsServiceRequestProto.decode(unzippedBuff);
|
||||
const json = data?.toJSON() as IExportLogsServiceRequest;
|
||||
const log1 = json.resourceLogs?.[0].scopeLogs?.[0].logRecords?.[0];
|
||||
assert.ok(typeof log1 !== 'undefined', "log doesn't exist");
|
||||
ensureExportedLogRecordIsCorrect(log1);
|
||||
|
||||
ensureExportLogsServiceRequestIsSet(json);
|
||||
assert.ok(spySetHeader.calledWith('Content-Encoding', 'gzip'));
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
fakeRequest.on('data', chunk => {
|
||||
buff = Buffer.concat([buff, chunk]);
|
||||
});
|
||||
|
||||
const clock = sinon.useFakeTimers();
|
||||
collectorExporter.export(logs, () => {});
|
||||
clock.tick(200);
|
||||
clock.restore();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('export - real http request destroyed before response received', () => {
|
||||
let collectorExporter: OTLPLogsExporter;
|
||||
let collectorExporterConfig: OTLPExporterNodeConfigBase;
|
||||
let logs: ReadableLogRecord[];
|
||||
const server = http.createServer((_, res) => {
|
||||
setTimeout(() => {
|
||||
res.statusCode = 200;
|
||||
res.end();
|
||||
}, 200);
|
||||
});
|
||||
before(done => {
|
||||
server.listen(8082, done);
|
||||
});
|
||||
after(done => {
|
||||
server.close(done);
|
||||
});
|
||||
it('should log the timeout request error message when timeout is 1', done => {
|
||||
collectorExporterConfig = {
|
||||
url: 'http://localhost:8082',
|
||||
timeoutMillis: 1,
|
||||
};
|
||||
collectorExporter = new OTLPLogsExporter(collectorExporterConfig);
|
||||
logs = [];
|
||||
logs.push(Object.assign({}, mockedReadableLogRecord));
|
||||
|
||||
collectorExporter.export(logs, result => {
|
||||
assert.strictEqual(result.code, ExportResultCode.FAILED);
|
||||
const error = result.error as OTLPExporterError;
|
||||
assert.ok(error !== undefined);
|
||||
assert.strictEqual(error.message, 'Request Timeout');
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should log the timeout request error message when timeout is 100', done => {
|
||||
collectorExporterConfig = {
|
||||
url: 'http://localhost:8082',
|
||||
timeoutMillis: 100,
|
||||
};
|
||||
collectorExporter = new OTLPLogsExporter(collectorExporterConfig);
|
||||
logs = [];
|
||||
logs.push(Object.assign({}, mockedReadableLogRecord));
|
||||
|
||||
collectorExporter.export(logs, result => {
|
||||
assert.strictEqual(result.code, ExportResultCode.FAILED);
|
||||
const error = result.error as OTLPExporterError;
|
||||
assert.ok(error !== undefined);
|
||||
assert.strictEqual(error.message, 'Request Timeout');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('export - real http request destroyed after response received', () => {
|
||||
let collectorExporter: OTLPLogsExporter;
|
||||
let collectorExporterConfig: OTLPExporterNodeConfigBase;
|
||||
let logs: ReadableLogRecord[];
|
||||
|
||||
const server = http.createServer((_, res) => {
|
||||
res.write('writing something');
|
||||
});
|
||||
before(done => {
|
||||
server.listen(8082, done);
|
||||
});
|
||||
after(done => {
|
||||
server.close(done);
|
||||
});
|
||||
it('should log the timeout request error message', done => {
|
||||
collectorExporterConfig = {
|
||||
url: 'http://localhost:8082',
|
||||
timeoutMillis: 300,
|
||||
};
|
||||
collectorExporter = new OTLPLogsExporter(collectorExporterConfig);
|
||||
logs = [];
|
||||
logs.push(Object.assign({}, mockedReadableLogRecord));
|
||||
|
||||
collectorExporter.export(logs, result => {
|
||||
assert.strictEqual(result.code, ExportResultCode.FAILED);
|
||||
const error = result.error as OTLPExporterError;
|
||||
assert.ok(error !== undefined);
|
||||
assert.strictEqual(error.message, 'Request Timeout');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.base.esm.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "build/esm",
|
||||
"rootDir": "src",
|
||||
"tsBuildInfoFile": "build/esm/tsconfig.esm.tsbuildinfo"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../../api"
|
||||
},
|
||||
{
|
||||
"path": "../../../packages/opentelemetry-core"
|
||||
},
|
||||
{
|
||||
"path": "../../../packages/opentelemetry-resources"
|
||||
},
|
||||
{
|
||||
"path": "../../../packages/opentelemetry-sdk-trace-base"
|
||||
},
|
||||
{
|
||||
"path": "../api-logs"
|
||||
},
|
||||
{
|
||||
"path": "../otlp-exporter-base"
|
||||
},
|
||||
{
|
||||
"path": "../otlp-proto-exporter-base"
|
||||
},
|
||||
{
|
||||
"path": "../otlp-transformer"
|
||||
},
|
||||
{
|
||||
"path": "../sdk-logs"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.base.esnext.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "build/esnext",
|
||||
"rootDir": "src",
|
||||
"tsBuildInfoFile": "build/esnext/tsconfig.esnext.tsbuildinfo"
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../../api"
|
||||
},
|
||||
{
|
||||
"path": "../../../packages/opentelemetry-core"
|
||||
},
|
||||
{
|
||||
"path": "../../../packages/opentelemetry-resources"
|
||||
},
|
||||
{
|
||||
"path": "../../../packages/opentelemetry-sdk-trace-base"
|
||||
},
|
||||
{
|
||||
"path": "../api-logs"
|
||||
},
|
||||
{
|
||||
"path": "../otlp-exporter-base"
|
||||
},
|
||||
{
|
||||
"path": "../otlp-proto-exporter-base"
|
||||
},
|
||||
{
|
||||
"path": "../otlp-transformer"
|
||||
},
|
||||
{
|
||||
"path": "../sdk-logs"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "build",
|
||||
"rootDir": "."
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"test/**/*.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../../api"
|
||||
},
|
||||
{
|
||||
"path": "../../../packages/opentelemetry-core"
|
||||
},
|
||||
{
|
||||
"path": "../../../packages/opentelemetry-resources"
|
||||
},
|
||||
{
|
||||
"path": "../../../packages/opentelemetry-sdk-trace-base"
|
||||
},
|
||||
{
|
||||
"path": "../api-logs"
|
||||
},
|
||||
{
|
||||
"path": "../otlp-exporter-base"
|
||||
},
|
||||
{
|
||||
"path": "../otlp-proto-exporter-base"
|
||||
},
|
||||
{
|
||||
"path": "../otlp-transformer"
|
||||
},
|
||||
{
|
||||
"path": "../sdk-logs"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -22,13 +22,8 @@ import {
|
|||
OTLPExporterConfigBase,
|
||||
sendWithXhr,
|
||||
} from '@opentelemetry/otlp-exporter-base';
|
||||
import * as root from '../../generated/root';
|
||||
|
||||
interface ExportRequestType<T, R = T & { toJSON: () => unknown }> {
|
||||
create(properties?: T): R;
|
||||
encode(message: T, writer?: protobuf.Writer): protobuf.Writer;
|
||||
decode(reader: protobuf.Reader | Uint8Array, length?: number): R;
|
||||
}
|
||||
import { getExportRequestProto } from '../util';
|
||||
|
||||
/**
|
||||
* Collector Exporter abstract base class
|
||||
|
@ -41,18 +36,6 @@ export abstract class OTLPProtoExporterBrowserBase<
|
|||
super(config);
|
||||
}
|
||||
|
||||
private _getExportRequestProto(
|
||||
clientType: ServiceClientType
|
||||
): ExportRequestType<ServiceRequest> {
|
||||
if (clientType === ServiceClientType.SPANS) {
|
||||
// eslint-disable-next-line
|
||||
return root.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest as unknown as ExportRequestType<ServiceRequest>;
|
||||
} else {
|
||||
// eslint-disable-next-line
|
||||
return root.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest as unknown as ExportRequestType<ServiceRequest>;
|
||||
}
|
||||
}
|
||||
|
||||
override send(
|
||||
objects: ExportItem[],
|
||||
onSuccess: () => void,
|
||||
|
@ -64,7 +47,7 @@ export abstract class OTLPProtoExporterBrowserBase<
|
|||
}
|
||||
|
||||
const serviceRequest = this.convert(objects);
|
||||
const exportRequestType = this._getExportRequestProto(
|
||||
const exportRequestType = getExportRequestProto(
|
||||
this.getServiceClientType()
|
||||
);
|
||||
const message = exportRequestType.create(serviceRequest);
|
||||
|
|
|
@ -14,11 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export {
|
||||
OTLPProtoExporterNodeBase,
|
||||
ExportRequestType,
|
||||
getExportRequestProto,
|
||||
send,
|
||||
} from './node';
|
||||
export { OTLPProtoExporterNodeBase, send } from './node';
|
||||
export { OTLPProtoExporterBrowserBase } from './browser';
|
||||
export { ServiceClientType } from './types';
|
||||
export { ExportRequestType, getExportRequestProto } from './util';
|
||||
|
|
|
@ -15,4 +15,4 @@
|
|||
*/
|
||||
|
||||
export { OTLPProtoExporterNodeBase } from './OTLPProtoExporterNodeBase';
|
||||
export { ExportRequestType, getExportRequestProto, send } from './util';
|
||||
export { send } from './util';
|
||||
|
|
|
@ -14,33 +14,14 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ServiceClientType } from '../types';
|
||||
import { OTLPProtoExporterNodeBase } from './OTLPProtoExporterNodeBase';
|
||||
import {
|
||||
CompressionAlgorithm,
|
||||
OTLPExporterError,
|
||||
sendWithHttp,
|
||||
} from '@opentelemetry/otlp-exporter-base';
|
||||
import type * as protobuf from 'protobufjs';
|
||||
import * as root from '../../generated/root';
|
||||
|
||||
export interface ExportRequestType<T, R = T & { toJSON: () => unknown }> {
|
||||
create(properties?: T): R;
|
||||
encode(message: T, writer?: protobuf.Writer): protobuf.Writer;
|
||||
decode(reader: protobuf.Reader | Uint8Array, length?: number): R;
|
||||
}
|
||||
|
||||
export function getExportRequestProto<ServiceRequest>(
|
||||
clientType: ServiceClientType
|
||||
): ExportRequestType<ServiceRequest> {
|
||||
if (clientType === ServiceClientType.SPANS) {
|
||||
return root.opentelemetry.proto.collector.trace.v1
|
||||
.ExportTraceServiceRequest as unknown as ExportRequestType<ServiceRequest>;
|
||||
} else {
|
||||
return root.opentelemetry.proto.collector.metrics.v1
|
||||
.ExportMetricsServiceRequest as unknown as ExportRequestType<ServiceRequest>;
|
||||
}
|
||||
}
|
||||
import { getExportRequestProto } from '../util';
|
||||
|
||||
export function send<ExportItem, ServiceRequest>(
|
||||
collector: OTLPProtoExporterNodeBase<ExportItem, ServiceRequest>,
|
||||
|
|
|
@ -17,4 +17,5 @@
|
|||
export enum ServiceClientType {
|
||||
SPANS,
|
||||
METRICS,
|
||||
LOGS,
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import * as root from '../generated/root';
|
||||
import { ServiceClientType } from './types';
|
||||
|
||||
export interface ExportRequestType<T, R = T & { toJSON: () => unknown }> {
|
||||
create(properties?: T): R;
|
||||
encode(message: T, writer?: protobuf.Writer): protobuf.Writer;
|
||||
decode(reader: protobuf.Reader | Uint8Array, length?: number): R;
|
||||
}
|
||||
|
||||
export function getExportRequestProto<ServiceRequest>(
|
||||
clientType: ServiceClientType
|
||||
): ExportRequestType<ServiceRequest> {
|
||||
if (clientType === ServiceClientType.SPANS) {
|
||||
return root.opentelemetry.proto.collector.trace.v1
|
||||
.ExportTraceServiceRequest as unknown as ExportRequestType<ServiceRequest>;
|
||||
} else if (clientType === ServiceClientType.LOGS) {
|
||||
return root.opentelemetry.proto.collector.logs.v1
|
||||
.ExportLogsServiceRequest as unknown as ExportRequestType<ServiceRequest>;
|
||||
} else {
|
||||
return root.opentelemetry.proto.collector.metrics.v1
|
||||
.ExportMetricsServiceRequest as unknown as ExportRequestType<ServiceRequest>;
|
||||
}
|
||||
}
|
|
@ -14,6 +14,9 @@
|
|||
{
|
||||
"path": "experimental/packages/exporter-logs-otlp-http/tsconfig.esm.json"
|
||||
},
|
||||
{
|
||||
"path": "experimental/packages/exporter-logs-otlp-proto/tsconfig.esm.json"
|
||||
},
|
||||
{
|
||||
"path": "experimental/packages/exporter-trace-otlp-http/tsconfig.esm.json"
|
||||
},
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
{
|
||||
"path": "experimental/packages/exporter-logs-otlp-http/tsconfig.esnext.json"
|
||||
},
|
||||
{
|
||||
"path": "experimental/packages/exporter-logs-otlp-proto/tsconfig.esnext.json"
|
||||
},
|
||||
{
|
||||
"path": "experimental/packages/exporter-trace-otlp-http/tsconfig.esnext.json"
|
||||
},
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"experimental/packages/api-logs",
|
||||
"experimental/packages/exporter-logs-otlp-grpc",
|
||||
"experimental/packages/exporter-logs-otlp-http",
|
||||
"experimental/packages/exporter-logs-otlp-proto",
|
||||
"experimental/packages/exporter-trace-otlp-grpc",
|
||||
"experimental/packages/exporter-trace-otlp-http",
|
||||
"experimental/packages/exporter-trace-otlp-proto",
|
||||
|
@ -71,6 +72,9 @@
|
|||
{
|
||||
"path": "experimental/packages/exporter-logs-otlp-http"
|
||||
},
|
||||
{
|
||||
"path": "experimental/packages/exporter-logs-otlp-proto"
|
||||
},
|
||||
{
|
||||
"path": "experimental/packages/exporter-trace-otlp-grpc"
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue