Skip to content

Commit

Permalink
fix: add with session metric (#147)
Browse files Browse the repository at this point in the history
  • Loading branch information
enzomerca authored Aug 19, 2024
1 parent ef9eeb7 commit 20f824d
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

### Added
- Session audit metrics

## [1.44.0] - 2024-08-14

### Changed
Expand Down
31 changes: 30 additions & 1 deletion node/directives/withSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import type { GraphQLField } from 'graphql'
import { defaultFieldResolver } from 'graphql'
import { SchemaDirectiveVisitor } from 'graphql-tools'

import sendSessionMetric, { SessionMetric } from '../metrics/session'

export class WithSession extends SchemaDirectiveVisitor {
public visitFieldDefinition(field: GraphQLField<any, any>) {
const { resolve = defaultFieldResolver } = field

field.resolve = async (root: any, args: any, context: any, info: any) => {
const {
clients: { session },
clients: { session, logger },
} = context

const token =
Expand All @@ -23,6 +25,33 @@ export class WithSession extends SchemaDirectiveVisitor {
})
.catch(() => null)

// we emit a metric for cases where the sessionData is null
// so we can identify use cases that are supposed to have sessionData
// but do not have it. We currently have a high volume of logs generated
// by such cases, so we need to identify and fix them.
const operation = field.astNode?.name?.value ?? context.request.url
const userAgent = context?.request?.headers['user-agent'] as string
const caller = context?.request?.headers['x-vtex-caller'] as string
const forwardedHost = context?.request?.headers[
'x-forwarded-host'
] as string

const hasSessionToken = !!context.vtex.sessionToken
const hasSessionTokenOnHeader = !!context.request.header?.sessiontoken
const hasSessionData = !!context.vtex.sessionData

const auditMetric = new SessionMetric(context?.vtex?.account, {
operation,
forwardedHost,
caller,
userAgent,
hasSessionToken,
hasSessionTokenOnHeader,
hasSessionData,
})

sendSessionMetric(logger, auditMetric)

return resolve(root, args, context, info)
}
}
Expand Down
46 changes: 46 additions & 0 deletions node/metrics/session.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { Logger } from '@vtex/api/lib/service/logger/logger'

import type { Metric } from '../clients/metrics'
import { B2B_METRIC_NAME, sendMetric } from '../clients/metrics'

export interface SessionAuditMetric {
operation: string
forwardedHost: string
caller: string
userAgent: string
hasSessionToken: boolean
hasSessionTokenOnHeader: boolean
hasSessionData: boolean
}

export class SessionMetric implements Metric {
public readonly description: string
public readonly kind: string
public readonly account: string
public readonly fields: SessionAuditMetric
public readonly name = B2B_METRIC_NAME
public error?: string

constructor(account: string, fields: SessionAuditMetric) {
this.account = account
this.fields = fields
this.kind = 'b2b-storefront-permissions-session-event'
this.description = 'Session metric event'
}
}

const sendSessionMetric = async (
logger: Logger,
sessionMetric: SessionMetric
) => {
try {
await sendMetric(sessionMetric)
} catch (error) {
logger.error({
error,
message: `Error to send metrics from session metric`,
})
}
}

export default sendSessionMetric

0 comments on commit 20f824d

Please sign in to comment.