feat: parse legacy k8s v1 cluster events (#300)

This commit is contained in:
Warren 2024-02-05 15:46:57 -08:00 committed by GitHub
parent d59bef130b
commit 41d80de1f8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 39 additions and 18 deletions

View file

@ -0,0 +1,6 @@
---
'@hyperdx/api': patch
'@hyperdx/app': patch
---
feat: parse legacy k8s v1 cluster events

View file

@ -464,31 +464,41 @@ if .hdx_platform == "vector-internal" {
}
# extract k8s event metadata
if .b.object.apiVersion == "events.k8s.io/v1" && .b.object.kind == "Event" {
# TODO: should we check "k8s.event.name" instead?
if .b."k8s.resource.name" == "events" && .b.object.kind == "Event" {
# set severity
if is_nullish(.b.level) && (.b.object.type == "Warning" || .b.object.type == "Normal") {
.b.level = .b.object.type
}
# check event format (cluster legacy v1 vs v1 events)
_targetObject = {}
if .b.object.apiVersion == "events.k8s.io/v1" && is_object(.b.object.regarding) {
_targetObject = .b.object.regarding
.b._hdx_body = .b.object.note
} else if .b.object.apiVersion == "v1" && is_object(.b.object.involvedObject) {
_targetObject = .b.object.involvedObject
.b._hdx_body = .b.object.message
}
# transform the attributes so that the log events use the k8s.* semantic conventions
# ref: https://docs.honeycomb.io/integrations/kubernetes/kubernetes-events/
if .b.object.regarding.kind == "Pod" {
.b."k8s.pod.name" = .b.object.regarding.name
.b."k8s.pod.uid" = .b.object.regarding.uid
.b."k8s.namespace.name" = .b.object.regarding.namespace
} else if .b.object.regarding.kind == "Node" {
.b."k8s.node.name" = .b.object.regarding.name
.b."k8s.node.uid" = .b.object.regarding.uid
} else if .b.object.regarding.kind == "Job" {
.b."k8s.job.name" = .b.object.regarding.name
.b."k8s.job.uid" = .b.object.regarding.uid
.b."k8s.namespace.name" = .b.object.regarding.namespace
} else if .b.object.regarding.kind == "CronJob" {
.b."k8s.cronjob.name" = .b.object.regarding.name
.b."k8s.cronjob.uid" = .b.object.regarding.uid
.b."k8s.namespace.name" = .b.object.regarding.namespace
if _targetObject.kind == "Pod" {
.b."k8s.pod.name" = _targetObject.name
.b."k8s.pod.uid" = _targetObject.uid
.b."k8s.namespace.name" = _targetObject.namespace
} else if _targetObject.kind == "Node" {
.b."k8s.node.name" = _targetObject.name
.b."k8s.node.uid" = _targetObject.uid
} else if _targetObject.kind == "Job" {
.b."k8s.job.name" = _targetObject.name
.b."k8s.job.uid" = _targetObject.uid
.b."k8s.namespace.name" = _targetObject.namespace
} else if _targetObject.kind == "CronJob" {
.b."k8s.cronjob.name" = _targetObject.name
.b."k8s.cronjob.uid" = _targetObject.uid
.b."k8s.namespace.name" = _targetObject.namespace
}
# set main message
.b._hdx_body = .b.object.note
}
# set severity after merging structured message (to avoid conflict)

View file

@ -54,6 +54,11 @@ const customColumnMap: { [level: string]: string } = {
userEmail: '_user_email',
userId: '_user_id',
userName: '_user_name',
// TODO: eventually we might want to materialize these fields
'object.regarding.kind':
"coalesce(_string_attributes['object.regarding.kind'], _string_attributes['object.involvedObject.kind'])",
'object.regarding.name':
"coalesce(_string_attributes['object.regarding.name'], _string_attributes['object.involvedObject.name'])",
};
export const customColumnMapType: {
[property: string]: 'string' | 'number' | 'bool';