Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions spec/fixtures/adot_fixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Fixture } from './general_fixtures'

export const anADOTCloudWatchEvent: Fixture = {
input: {
deliveryStreamArn: 'someDeliveryStreamArn',
invocationId: 'someId',
region: 'eu-west-1',
records: [{
approximateArrivalTimestamp: 1234,
recordId: 'LogEvent-1',
data: Buffer.from(JSON.stringify({
owner: '223851549868',
logGroup: 'test-12_adot_frontend',
logStream: 'logStream',
subscriptionFilters: [],
messageType: 'DATA_MESSAGE',
logEvents: [
{
id: 'cloudwatch-log-message-id-1',
timestamp: 1234,
message: '2025/05/28 10:13:36 ADOT Collector version: v0.43.3'
},
{
id: 'cloudwatch-log-gmessage-id-2',
timestamp: 1235,
message: '2025-05-28T10:13:36.838Z warn awsemfexporter@v0.117.0/emf_exporter.go:92 the default value for DimensionRollupOption will be changing to NoDimensionRollupin a future release. See https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/23997 for moreinformation {"kind": "exporter", "data_type": "metrics", "name": "awsemf"}'
}
]
})).toString('base64')
}]
},
expected: {
records: [{
result: 'Ok',
recordId: 'LogEvent-1',
data: Buffer.from([
{
host: 'logStream',
source: 'adot',
sourcetype: 'generic_single_line',
index: 'pay_devops',
event: '2025/05/28 10:13:36 ADOT Collector version: v0.43.3',
fields: {
account: 'test',
environment: 'test-12',
service: 'frontend'
},
time: 1234.000
},
{
host: 'logStream',
source: 'adot',
sourcetype: 'generic_single_line',
index: 'pay_devops',
event: '2025-05-28T10:13:36.838Z warn awsemfexporter@v0.117.0/emf_exporter.go:92 the default value for DimensionRollupOption will be changing to NoDimensionRollupin a future release. See https://github.com/open-telemetry/opentelemetry-collector-contrib/issues/23997 for moreinformation {"kind": "exporter", "data_type": "metrics", "name": "awsemf"}',
fields: {
account: 'test',
environment: 'test-12',
service: 'frontend'
},
time: 1235.000
}
].map(x => JSON.stringify(x)).join('\n')).toString('base64')
}]
}
}
14 changes: 14 additions & 0 deletions spec/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import {
anInvalidApplicationLogFirehoseTransformationEventRecord
} from './fixtures/application_fixtures'

import {
anADOTCloudWatchEvent
} from './fixtures/adot_fixtures'

import {
aBastionLogCloudWatchEvent
} from './fixtures/bastion_fixtures'
Expand Down Expand Up @@ -81,6 +85,16 @@ describe('Processing CloudWatchLogEvents', () => {
expect(Buffer.from(result.records[1].data as string, 'base64').toString()).toEqual(Buffer.from(expectedSecondRecord.data as string, 'base64').toString())
})
})
describe('From ADOT', () => {
test('should transform adot logs from CloudWatch', async () => {
const result = await handler(anADOTCloudWatchEvent.input, mockContext, mockCallback) as FirehoseTransformationResult

const expectedRecord = anADOTCloudWatchEvent.expected.records[0]
expect(result.records[0].result).toEqual(expectedRecord.result)
expect(result.records[0].recordId).toEqual(expectedRecord.recordId)
expect(Buffer.from(result.records[0].data as string, 'base64').toString()).toEqual(Buffer.from(expectedRecord.data as string, 'base64').toString())
})
})
describe('From Bastion', () => {
test('should transform bastion logs from CloudWatch', async () => {
const result = await handler(aBastionLogCloudWatchEvent.input, mockContext, mockCallback) as FirehoseTransformationResult
Expand Down
3 changes: 3 additions & 0 deletions src/extractTime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ export function parseTimeFromLog(log: string, logType: CloudWatchLogTypes): numb
switch (logType) {
case CloudWatchLogTypes.app:
return extractAppLogTime(log)
case CloudWatchLogTypes.adot:
// Adot has many different time formats, so we'll rely on the cloudwatch timestamp instead
return undefined
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might want to remove console.log('Using cloudwatch event time') on line 129, as it will be logged for every adot log line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As it happens though, with ADOT when you have the log level as WARN it basically only logs on startup and shutdown (unless things are going wrong I guess).

But I think you're still right, it might be good to gate the logs behind a debug flag like with the current lambdas, and the s3 to firehose one.

I'll do that as a follow on

case CloudWatchLogTypes.bastion:
return extractBastionLogTime(log)
case CloudWatchLogTypes.squid:
Expand Down
5 changes: 5 additions & 0 deletions src/transformData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ function sourceTypeFromLogGroup(logType: CloudWatchLogTypes, msg: string): strin
switch (logType) {
case CloudWatchLogTypes.app:
return 'ST004:application_json'
case CloudWatchLogTypes.adot:
// ADOT has logs in many formats, so better to just set a geenric source type
return 'generic_single_line'
case CloudWatchLogTypes.bastion:
return 'linux_bastion'
case CloudWatchLogTypes['nginx-forward-proxy']:
Expand Down Expand Up @@ -184,6 +187,8 @@ function indexFromLogType(logType: CloudWatchLogTypes): string {
switch (logType) {
case CloudWatchLogTypes.app:
return 'pay_application'
case CloudWatchLogTypes.adot:
return 'pay_devops'
case CloudWatchLogTypes.bastion:
return 'pay_host'
case CloudWatchLogTypes['nginx-forward-proxy']:
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export type EnvVars = {
}

export enum CloudWatchLogTypes {
'adot',
'app',
'apt',
'audit',
Expand Down
Loading