Skip to content

Commit

Permalink
Add telemetry:update, change capabilities to signals
Browse files Browse the repository at this point in the history
  • Loading branch information
eablack committed Oct 21, 2024
1 parent 07a820f commit d872812
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 25 deletions.
16 changes: 2 additions & 14 deletions packages/cli/src/commands/telemetry/add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {Command, flags as Flags} from '@heroku-cli/command'
import {Args, ux} from '@oclif/core'
import {TelemetryDrain} from '../../lib/types/telemetry'
import heredoc from 'tsheredoc'

import {validateAndFormatSignal} from '../../lib/telemetry/util'
export default class Add extends Command {
static description = 'Add and configure a new telemetry drain. Defaults to collecting all telemetry unless otherwise specified.'

Expand All @@ -24,18 +24,6 @@ export default class Add extends Command {
$ heroku telemetry:add --signal logs,traces --endpoint https://my-endpoint.com --transport http 'x-drain-example-team: API_KEY x-drain-example-dataset: METRICS_DATASET'
`)

private validateAndFormatSignal = function (signalInput: string | undefined): string[] {
const signalOptions = ['traces', 'metrics', 'logs']
if (!signalInput || signalInput === 'all') return signalOptions
const signalArray = signalInput.split(',')
signalArray.forEach(signal => {
if (!signalOptions.includes(signal)) {
ux.error(`Invalid signal option: ${signalArray}. Run heroku telemetry:add --help to see signal options.`, {exit: 1})
}
})
return signalArray
}

private getTypeAndName = function (app: string | undefined, space: string | undefined) {
if (app) {
return {type: 'app', name: app}
Expand All @@ -54,7 +42,7 @@ export default class Add extends Command {
type: typeAndName.type,
id: typeAndName.name,
},
signals: this.validateAndFormatSignal(signal),
signals: validateAndFormatSignal(signal),
exporter: {
endpoint,
type: `otlp${transport}`,
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/telemetry/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default class Index extends Command {
telemetryDrains,
{
ID: {get: telemetryDrain => telemetryDrain.id},
Signals: {get: telemetryDrain => telemetryDrain.capabilities},
Signals: {get: telemetryDrain => telemetryDrain.signals},
Endpoint: {get: telemetryDrain => telemetryDrain.exporter.endpoint},
[ownerType]: {get: telemetryDrain => telemetryDrain.owner.name},
},
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/telemetry/info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default class Info extends Command {
const drainType = telemetryDrain.owner.type.charAt(0).toUpperCase() + telemetryDrain.owner.type.slice(1)
ux.styledObject({
[drainType]: telemetryDrain.owner.name,
Signals: telemetryDrain.capabilities.join(', '),
Signals: telemetryDrain.signals.join(', '),
Endpoint: telemetryDrain.exporter.endpoint,
Kind: telemetryDrain.exporter.type,
Headers: telemetryDrain.exporter.headers,
Expand Down
63 changes: 63 additions & 0 deletions packages/cli/src/commands/telemetry/update.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import {flags as Flags, Command} from '@heroku-cli/command'
import {Args, ux} from '@oclif/core'
import {TelemetryDrain, TelemetryDrainWithOptionalKeys, TelemetryExporterWithOptionalKeys} from '../../lib/types/telemetry'
import heredoc from 'tsheredoc'
import {validateAndFormatSignal} from '../../lib/telemetry/util'

export default class Update extends Command {
static topic = 'telemetry'
static description = 'updates a telemetry drain'
static args = {
telemetry_drain_id: Args.string({required: true, description: 'ID of the drain to update'}),
headers: Args.string({description: 'custom headers to configure the drain in json format'}),
}

static flags = {
signal: Flags.string({default: 'all', description: 'comma-delimited list of signals to collect (traces, metrics, logs). Use "all" to collect all signals.'}),
endpoint: Flags.string({description: 'drain url'}),
transport: Flags.string({options: ['http', 'gprc'], description: 'transport protocol for the drain'}),
}

public async run(): Promise<void> {
const {args, flags} = await this.parse(Update)
const {telemetry_drain_id, headers} = args
const {signal, endpoint, transport} = flags
if (!(headers || signal || endpoint || transport)) {
ux.error(heredoc(`
Requires either --signal, --endpoint, --transport or HEADERS to be provided.
See more help with --help
`))
}

const drainConfig: TelemetryDrainWithOptionalKeys = {}
if (signal) {
drainConfig.signals = validateAndFormatSignal(signal)
}

if (headers || endpoint || transport) {
const exporter: TelemetryExporterWithOptionalKeys = {}
if (headers) {
exporter.headers = JSON.parse(headers)
}

if (endpoint) {
exporter.endpoint = endpoint
}

if (transport) {
exporter.type = `otlp${transport}`
}

drainConfig.exporter = exporter
}

const {body: telemetryDrain} = await this.heroku.patch<TelemetryDrain>(`/telemetry-drains/${telemetry_drain_id}`, {
headers: {
Accept: 'application/vnd.heroku+json; version=3.sdk',
},
body: drainConfig,
})
ux.action.start(`Updating telemetry drain ${telemetry_drain_id}, which was configured for ${telemetryDrain.owner.type} ${telemetryDrain.owner.name}`)
ux.action.stop()
}
}
13 changes: 13 additions & 0 deletions packages/cli/src/lib/telemetry/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {ux} from '@oclif/core'

export function validateAndFormatSignal(signalInput: string | undefined): string[] {
const signalOptions = ['traces', 'metrics', 'logs']
if (!signalInput || signalInput === 'all') return signalOptions
const signalArray = signalInput.split(',')
signalArray.forEach(signal => {
if (!signalOptions.includes(signal)) {
ux.error(`Invalid signal option: ${signalArray}. Run heroku telemetry:add --help to see signal options.`, {exit: 1})
}
})
return signalArray
}
7 changes: 5 additions & 2 deletions packages/cli/src/lib/types/telemetry.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export type TelemetryDrains = TelemetryDrain[]

export type TelemetryDrain = {
id: string;
capabilities: string[];
signals: string[];
owner: TelemetryDrainOwner;
exporter: TelemetryExporter
}
Expand All @@ -14,7 +14,10 @@ type TelemetryDrainOwner = {
}

type TelemetryExporter = {
type: 'otlphttp' | 'otlpgrpc';
type: string;
endpoint: string;
headers: unknown;
}

type TelemetryDrainWithOptionalKeys = Partial<TelemetryDrain, 'exporter'>
type TelemetryExporterWithOptionalKeys = Partial<TelemetryExporter>
6 changes: 3 additions & 3 deletions packages/cli/test/fixtures/telemetry/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {TelemetryDrain} from '../../../src/lib/types/telemetry'
export const spaceTelemetryDrain1: TelemetryDrain = {
id: '44444321-5717-4562-b3fc-2c963f66afa6',
owner: {id: '12345678-5717-4562-b3fc-2c963f66afa6', type: 'space', name: 'myspace'},
capabilities: ['traces', 'metrics', 'logs'],
signals: ['traces', 'metrics', 'logs'],
exporter: {
type: 'otlphttp',
endpoint: 'https://api.honeycomb.io/',
Expand All @@ -17,7 +17,7 @@ export const spaceTelemetryDrain1: TelemetryDrain = {
export const appTelemetryDrain1: TelemetryDrain = {
id: '3fa85f64-5717-4562-b3fc-2c963f66afa6',
owner: {id: '87654321-5717-4562-b3fc-2c963f66afa6', type: 'app', name: 'myapp'},
capabilities: ['traces', 'metrics'],
signals: ['traces', 'metrics'],
exporter: {
type: 'otlphttp',
endpoint: 'https://api.honeycomb.io/',
Expand All @@ -31,7 +31,7 @@ export const appTelemetryDrain1: TelemetryDrain = {
export const appTelemetryDrain2: TelemetryDrain = {
id: '55555f64-5717-4562-b3fc-2c963f66afa6',
owner: {id: '87654321-5717-4562-b3fc-2c963f66afa6', type: 'app', name: 'myapp'},
capabilities: ['logs'],
signals: ['logs'],
exporter: {
type: 'otlphttp',
endpoint: 'https://api.papertrail.com/',
Expand Down
8 changes: 4 additions & 4 deletions packages/cli/test/unit/commands/telemetry/info.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('telemetry:info', function () {
spaceTelemetryDrain = {
id: '44444321-5717-4562-b3fc-2c963f66afa6',
owner: {id: spaceId, type: 'space', name: 'myspace'},
capabilities: ['traces', 'metrics', 'logs'],
signals: ['traces', 'metrics', 'logs'],
exporter: {
type: 'otlphttp',
endpoint: 'https://api.honeycomb.io/',
Expand All @@ -29,7 +29,7 @@ describe('telemetry:info', function () {
appTelemetryDrain = {
id: '3fa85f64-5717-4562-b3fc-2c963f66afa6',
owner: {id: appId, type: 'app', name: 'myapp'},
capabilities: ['traces', 'metrics'],
signals: ['traces', 'metrics'],
exporter: {
type: 'otlphttp',
endpoint: 'https://api.honeycomb.io/',
Expand All @@ -56,7 +56,7 @@ describe('telemetry:info', function () {
expectOutput(stdout.output, heredoc(`
=== ${spaceTelemetryDrain.id}
Space: ${spaceTelemetryDrain.owner.name}
Signals: ${spaceTelemetryDrain.capabilities.join(', ')}
Signals: ${spaceTelemetryDrain.signals.join(', ')}
Endpoint: ${spaceTelemetryDrain.exporter.endpoint}
Kind: ${spaceTelemetryDrain.exporter.type}
Headers: x-honeycomb-team: 'your-api-key', x-honeycomb-dataset: 'your-dataset'
Expand All @@ -74,7 +74,7 @@ describe('telemetry:info', function () {
expectOutput(stdout.output, heredoc(`
=== ${appTelemetryDrain.id}
App: ${appTelemetryDrain.owner.name}
Signals: ${appTelemetryDrain.capabilities.join(', ')}
Signals: ${appTelemetryDrain.signals.join(', ')}
Endpoint: ${appTelemetryDrain.exporter.endpoint}
Kind: ${appTelemetryDrain.exporter.type}
Headers: x-honeycomb-team: 'your-api-key', x-honeycomb-dataset: 'your-dataset'
Expand Down

0 comments on commit d872812

Please sign in to comment.