Skip to content

Commit 6d569fe

Browse files
committed
support for clickhouse, datadog, and blackhole
1 parent 267f876 commit 6d569fe

3 files changed

Lines changed: 225 additions & 54 deletions

File tree

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ on:
44
push:
55

66
env:
7-
ROTEL_VERSION: "tags/v0.0.1-alpha1"
7+
ROTEL_VERSION: "tags/v0.0.1-alpha22"
88

99
jobs:
1010
publish-npm-binaries:

npm/app/config.ts

Lines changed: 223 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ export interface OTLPExporterEndpoint {
2424
// TODO: when we have more, include a key that defines this exporter type
2525
export interface OTLPExporter extends OTLPExporterEndpoint {
2626
_type?: string
27-
traces?: OTLPExporterEndpoint | DatadogExporter;
28-
metrics?: OTLPExporterEndpoint;
29-
logs?: OTLPExporterEndpoint;
27+
traces?: OTLPExporterEndpoint | DatadogExporter | BlackholeExporter;
28+
metrics?: OTLPExporterEndpoint | BlackholeExporter;
29+
logs?: OTLPExporterEndpoint | BlackholeExporter;
3030
}
3131

3232
export interface DatadogExporter {
@@ -36,6 +36,24 @@ export interface DatadogExporter {
3636
api_key?: string
3737
}
3838

39+
export interface BlackholeExporter {
40+
_type?: string
41+
}
42+
43+
44+
export interface ClickhouseExporter {
45+
_type?: string
46+
endpoint?: string
47+
database?: string
48+
table_prefix?: string
49+
compression?: string
50+
async_insert?: boolean
51+
user?: string
52+
password?: string
53+
enable_json?: boolean
54+
}
55+
56+
3957
export interface Options {
4058
enabled?: boolean;
4159
pid_file?: string;
@@ -47,8 +65,8 @@ export interface Options {
4765
otlp_receiver_traces_disabled?: boolean;
4866
otlp_receiver_metrics_disabled?: boolean;
4967
otlp_receiver_logs_disabled?: boolean;
50-
exporter?: OTLPExporter | DatadogExporter;
51-
exporters?: Record<string, OTLPExporter | DatadogExporter | undefined>
68+
exporter?: OTLPExporter | DatadogExporter | ClickhouseExporter | BlackholeExporter;
69+
exporters?: Record<string, OTLPExporter | DatadogExporter | ClickhouseExporter |BlackholeExporter | undefined>
5270
exporters_metrics?: string[] | undefined
5371
exporters_traces?: string[] | undefined
5472
exporters_logs?: string[] | undefined
@@ -97,7 +115,7 @@ export class Config {
97115
};
98116

99117
const exporters = as_lower(rotel_env("EXPORTERS"));
100-
if (exporters !== null && exporters !== undefined) {
118+
if (exporters !== undefined) {
101119
env["exporters"] = {};
102120
for (const exporterStr of exporters.split(",")) {
103121
let name = exporterStr;
@@ -106,7 +124,7 @@ export class Config {
106124
[name, value] = exporterStr.split(":", 2);
107125
}
108126

109-
let exporter: OTLPExporter | DatadogExporter | undefined = undefined;
127+
let exporter: OTLPExporter | DatadogExporter | ClickhouseExporter | BlackholeExporter | undefined = undefined;
110128
let pfx = "EXPORTER_" + name.toUpperCase + "_"
111129
switch(value) {
112130
case "otlp":
@@ -124,6 +142,24 @@ export class Config {
124142
api_key: rotel_env(pfx + "API_KEY"),
125143
};
126144
exporter = datadogExporter;
145+
case "blackhole":
146+
const blackholeExporter: BlackholeExporter = {
147+
_type: "blackhole",
148+
}
149+
exporter = blackholeExporter;
150+
case "clickhouse":
151+
const clickhouseExporter: ClickhouseExporter = {
152+
_type: "clickhouse",
153+
endpoint: rotel_env(pfx + "ENDPOINT"),
154+
database: rotel_env(pfx + "DATABASE"),
155+
table_prefix: rotel_env(pfx + "TABLE_PREFIX"),
156+
compression: rotel_env(pfx + "COMPRESSION"),
157+
async_insert: as_bool(rotel_env(pfx + "ASYNC_INSERT")),
158+
user: rotel_env(pfx + "USER"),
159+
password: rotel_env(pfx + "PASSWORD"),
160+
enable_json: as_bool(rotel_env(pfx + "ENABLE_JSON")),
161+
}
162+
exporter = clickhouseExporter;
127163
}
128164
if (exporter !== undefined) {
129165
env.exporters[name] = exporter;
@@ -156,14 +192,34 @@ export class Config {
156192
exporter.logs = logs_endpoint;
157193
}
158194
} else if (exporter_type === "datadog") {
159-
const pfx = "DATADOG_EXPORTER_"
160-
var c: DatadogExporter = {
195+
const pfx = "DATADOG_EXPORTER_";
196+
var d: DatadogExporter = {
161197
_type: "datadog",
162198
region: rotel_env(pfx + "REGION"),
163199
custom_endpoint: rotel_env(pfx + "CUSTOM_ENDPOINT"),
164200
api_key: rotel_env(pfx + "API_KEY"),
165201
}
166-
env.exporter = c;
202+
env.exporter = d;
203+
} else if (exporter_type === "blackhole") {
204+
const pfx = "BLACKHOLE_EXPORTER_";
205+
var b: BlackholeExporter = {
206+
_type: "blackhole",
207+
}
208+
env.exporter = b
209+
} else if (exporter_type === "clickhouse") {
210+
const pfx = "CLICKHOUSE_EXPORTER_"
211+
var c: ClickhouseExporter = {
212+
_type: "clickhouse",
213+
endpoint: rotel_env(pfx + "ENDPOINT"),
214+
database: rotel_env(pfx + "DATABASE"),
215+
table_prefix: rotel_env(pfx + "TABLE_PREFIX"),
216+
compression: rotel_env(pfx + "COMPRESSION"),
217+
async_insert: as_bool(rotel_env(pfx + "ASYNC_INSERT")),
218+
user: rotel_env(pfx + "USER"),
219+
password: rotel_env(pfx + "PASSWORD"),
220+
enable_json: as_bool(rotel_env(pfx + "ENABLE_JSON")),
221+
}
222+
env.exporter = c;
167223
}
168224
}
169225

@@ -177,20 +233,35 @@ export class Config {
177233
return final_env;
178234
}
179235

180-
static _load_datadog_exporter_options_from_env(pfx: string): DatadogExporter {
181-
const datadogExporter: DatadogExporter = {
182-
region: rotel_env(pfx + "REGION"),
183-
custom_endpoint: rotel_env(pfx + "CUSTOM_ENDPOINT"),
184-
api_key: rotel_env(pfx + "API_KEY"),
236+
static otlp_exporter(config?: Partial<OTLPExporter>): OTLPExporter {
237+
return {
238+
_type: "otlp",
239+
...config
240+
};
241+
}
242+
243+
static datadog_exporter(config?: Partial<DatadogExporter>): DatadogExporter {
244+
return {
245+
_type: "datadog",
246+
...config
247+
};
248+
}
249+
250+
static blackhole_exporter(config?: Partial<BlackholeExporter>): BlackholeExporter {
251+
return {
252+
_type: "blackhole",
253+
...config
185254
};
186-
return datadogExporter;
187255
}
188256

257+
static clickhouse_exporter(config?: Partial<ClickhouseExporter>): ClickhouseExporter {
258+
return {
259+
_type: "clickhouse",
260+
...config
261+
}
262+
}
263+
189264
static _load_otlp_exporter_options_from_env(pfx: string, endpoint_type: string | null): OTLPExporter | OTLPExporterEndpoint | undefined {
190-
// let pfx = "OTLP_EXPORTER_";
191-
// if (endpoint_type !== null) {
192-
// pfx += `${endpoint_type}_`;
193-
// }
194265
const endpoint: OTLPExporterEndpoint = {
195266
endpoint: rotel_env(pfx + "ENDPOINT"),
196267
protocol: as_lower(rotel_env(pfx + "PROTOCOL")),
@@ -236,33 +307,45 @@ export class Config {
236307
"OTLP_RECEIVER_METRICS_DISABLED": opts.otlp_receiver_metrics_disabled,
237308
"OTLP_RECEIVER_LOGS_DISABLED": opts.otlp_receiver_logs_disabled,
238309
};
239-
240-
const exporter = opts.exporter;
241-
if (exporter !== undefined) {
242-
console.log("exporter._type in build_agent_environment is " + exporter._type);
243-
switch (exporter._type) {
244-
case "otlp" || undefined:
245-
const otlpExporter: OTLPExporter = <OTLPExporter>exporter;
246-
_set_otlp_exporter_agent_env(updates, null, exporter);
247-
248-
const traces = otlpExporter.traces;
249-
if (traces !== undefined) {
250-
_set_otlp_exporter_agent_env(updates, "TRACES", traces);
251-
}
252-
253-
const metrics = otlpExporter.metrics;
254-
if (metrics !== undefined) {
255-
_set_otlp_exporter_agent_env(updates, "METRICS", metrics);
256-
}
257-
const logs = otlpExporter.logs;
258-
if (logs !== undefined) {
259-
_set_otlp_exporter_agent_env(updates, "LOGS", logs);
260-
}
261-
break;
262-
case "datadog":
263-
const datadogExporter: DatadogExporter = <DatadogExporter>exporter;
264-
_set_datadog_exporter_agent_env(updates, "DATADOG_EXPORTER_" , exporter);
265-
break;
310+
311+
const exporters = opts.exporters;
312+
if (exporters) {
313+
const exportersList: string[] = [];
314+
for (const [name, exporter] of Object.entries(exporters)) {
315+
const exporterType = (exporter as Record<string, any>).get?.("_type") || (exporter as any)["_type"];
316+
if (name === exporterType) {
317+
exportersList.push(`${name}`);
318+
} else {
319+
exportersList.push(`${name}:${exporterType}`);
320+
}
321+
const pfx = `EXPORTER_${name.toUpperCase()}_`;
322+
this._set_exporter_agent_env(updates, pfx, exporter);
323+
}
324+
Object.assign(updates, {
325+
"EXPORTERS": exportersList.join(","),
326+
});
327+
328+
if (opts.exporters_metrics !== null) {
329+
Object.assign(updates, {
330+
"EXPORTERS_METRICS": opts.exporters_metrics?.join(","),
331+
});
332+
}
333+
334+
if (opts.exporters_traces !== null) {
335+
Object.assign(updates, {
336+
"EXPORTERS_TRACES": opts.exporters_traces?.join(","),
337+
});
338+
}
339+
340+
if (opts.exporters_logs !== null) {
341+
Object.assign(updates, {
342+
"EXPORTERS_LOGS": opts.exporters_logs?.join(","),
343+
});
344+
}
345+
} else {
346+
const exporter = opts.exporter;
347+
if (exporter !== undefined) {
348+
this._set_exporter_agent_env(updates, null, exporter)
266349
}
267350
}
268351

@@ -285,8 +368,64 @@ export class Config {
285368
}
286369
}
287370

371+
//this.log_spawn_env(spawn_env);
288372
return spawn_env;
289373
}
374+
375+
// for local dev debugging purposes.
376+
log_spawn_env(spawn_env: { [x: string]: string | undefined; TZ?: string | undefined; }): void {
377+
console.log("spawn_env contents:");
378+
for (const [key, value] of Object.entries(spawn_env)) {
379+
console.log(` ${key}: ${value}`);
380+
}
381+
}
382+
383+
_set_exporter_agent_env(
384+
updates: Record<string, any>,
385+
pfx: string | null,
386+
exporter: OTLPExporter | DatadogExporter | undefined
387+
): void {
388+
const expType = (exporter as Record<string, any>).get?.("_type") || (exporter as any)["_type"];
389+
390+
if (expType === "datadog") {
391+
const d: DatadogExporter = exporter as DatadogExporter;
392+
_set_datadog_exporter_agent_env(updates, pfx, d);
393+
return;
394+
}
395+
396+
if (expType === "blackhole") {
397+
const b: BlackholeExporter = exporter as BlackholeExporter;
398+
_set_blackhole_exporter_agent_env(updates, pfx, b);
399+
return;
400+
}
401+
402+
if (expType == "clickhouse") {
403+
const c: ClickhouseExporter = exporter as ClickhouseExporter;
404+
_set_clickhouse_exporter_agent_env(updates, pfx, c)
405+
return;
406+
}
407+
408+
//
409+
// Fall through to OTLP exporter
410+
//
411+
const e: OTLPExporter = exporter as OTLPExporter;
412+
_set_otlp_exporter_agent_env(updates, pfx, null, e);
413+
414+
const traces = (exporter as any).get?.("traces") || (exporter as any)["traces"];
415+
if (traces !== null && traces !== undefined) {
416+
_set_otlp_exporter_agent_env(updates, null, "TRACES", traces);
417+
}
418+
419+
const metrics = (exporter as any).get?.("metrics") || (exporter as any)["metrics"];
420+
if (metrics !== null && metrics !== undefined) {
421+
_set_otlp_exporter_agent_env(updates, null, "METRICS", metrics);
422+
}
423+
424+
const logs = (exporter as any).get?.("logs") || (exporter as any)["logs"];
425+
if (logs !== null && logs !== undefined) {
426+
_set_otlp_exporter_agent_env(updates, null, "LOGS", logs); // Note: was "metrics" in original, assuming this is correct
427+
}
428+
}
290429

291430
// Perform some minimal validation for now, we can expand this as needed
292431
validate(): boolean | null {
@@ -303,7 +442,6 @@ export class Config {
303442
case "otlp":
304443
const otlpExporter: OTLPExporter = <OTLPExporter>exporter;
305444
const protocol = otlpExporter.protocol;
306-
console.log("protocol is " + protocol);
307445
if (protocol !== undefined && protocol !== 'grpc' && protocol !== 'http') {
308446
console.error("exporter protocol must be 'grpc' or 'http'");
309447
return false;
@@ -322,7 +460,19 @@ export class Config {
322460
}
323461
}
324462

325-
function _set_datadog_exporter_agent_env(updates: Record<string, any>, pfx: string, exporter: DatadogExporter) {
463+
function _set_blackhole_exporter_agent_env(updates: Record<string, any>, pfx: string | null, exporter: BlackholeExporter) {
464+
if (pfx === null) {
465+
pfx = "BLACKHOLE_EXPORTER_";
466+
}
467+
Object.assign(updates, {
468+
[pfx + "EXPORTER"]: "blackhole",
469+
})
470+
}
471+
472+
function _set_datadog_exporter_agent_env(updates: Record<string, any>, pfx: string | null, exporter: DatadogExporter) {
473+
if (pfx === null) {
474+
pfx = "DATADOG_EXPORTER_";
475+
}
326476
Object.assign(updates, {
327477
[pfx + "EXPORTER"]: "datadog",
328478
[pfx + "REGION"]: exporter.region,
@@ -331,8 +481,30 @@ function _set_datadog_exporter_agent_env(updates: Record<string, any>, pfx: stri
331481
})
332482
}
333483

334-
function _set_otlp_exporter_agent_env(updates: Record<string, any>, endpoint_type: string | null, exporter: OTLPExporter | OTLPExporterEndpoint | null): void {
335-
let pfx = "OTLP_EXPORTER_";
484+
function _set_clickhouse_exporter_agent_env(updates: Record<string, any>, pfx: string | null, exporter: ClickhouseExporter) {
485+
if (pfx === null) {
486+
pfx = "CLICKHOUSE_EXPORTER_"
487+
updates.update({
488+
"EXPORTER": "clickhouse",
489+
})
490+
}
491+
492+
Object.assign(updates, {
493+
[pfx + "ENDPOINT"]: exporter.endpoint,
494+
[pfx + "DATABASE"]: exporter.database,
495+
[pfx + "TABLE_PREFIX"]: exporter.table_prefix,
496+
[pfx + "COMPRESSION"]: exporter.compression,
497+
[pfx + "ASYNC_INSERT"]: exporter.async_insert,
498+
[pfx + "USER"]: exporter.user,
499+
[pfx + "PASSWORD"]: exporter.password,
500+
[pfx + "ENABLE_JSON"]: exporter.enable_json,
501+
})
502+
}
503+
504+
function _set_otlp_exporter_agent_env(updates: Record<string, any>, pfx: string | null, endpoint_type: string | null, exporter: OTLPExporter | OTLPExporterEndpoint | null): void {
505+
if (pfx === null) {
506+
pfx = "OTLP_EXPORTER_";
507+
}
336508
if (endpoint_type !== null) {
337509
pfx += `${endpoint_type}_`;
338510
}
@@ -414,8 +586,6 @@ function as_bool(value: string | null | undefined): boolean | undefined {
414586
}
415587

416588
function rotel_env(base_key: string): string | undefined {
417-
// let key = rotel_expand_env_key(base_key);
418-
// console.log("key is " + key);
419589
const envVar = process.env[rotel_expand_env_key(base_key)];
420590
return envVar !== undefined ? envVar : undefined;
421591
}

npm/app/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
// SPDX-License-Identifier: Apache-2.0
22
export { Client as Rotel } from "./client"
3+
export { Config as Config} from "./config"

0 commit comments

Comments
 (0)