Skip to content

Commit

Permalink
massively reduce sentry dep size
Browse files Browse the repository at this point in the history
  • Loading branch information
joshbalfour committed Apr 9, 2024
1 parent 63abf82 commit dd846a3
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 61 deletions.
2 changes: 1 addition & 1 deletion packages/modules/edge-api-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"main": "dist/index.js",
"types": "dist/index.d.ts",
"description": "Provides convenience wrappers for accepting and responding to [@reapit-cdk/edge-api]('../../constructs/edge-api/readme.md') lambda requests.",
"version": "0.0.9",
"version": "0.0.11",
"homepage": "https://github.com/reapit/ts-cdk-constructs/blob/main/packages/modules/edge-api-sdk",
"readme": "https://github.com/reapit/ts-cdk-constructs/blob/main/packages/modules/edge-api-sdk/readme.md",
"bugs": {
Expand Down
2 changes: 1 addition & 1 deletion packages/modules/edge-api-sdk/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export * from './edge-api-sdk'
export * from './types'
export * from './config'
export * from './sentry'
export * from './sentry/sentry'
59 changes: 0 additions & 59 deletions packages/modules/edge-api-sdk/src/sentry.ts

This file was deleted.

57 changes: 57 additions & 0 deletions packages/modules/edge-api-sdk/src/sentry/module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { posix, sep } from 'path'
import { dirname } from '@sentry/utils'

/** normalizes Windows paths */
function normalizeWindowsPath(path: string): string {
return path
.replace(/^[A-Z]:/, '') // remove Windows-style prefix
.replace(/\\/g, '/') // replace all `\` instances with `/`
}

/** Creates a function that gets the module name from a filename */
export function createGetModuleFromFilename(
basePath: string = process.argv[1] ? dirname(process.argv[1]) : process.cwd(),
isWindows: boolean = sep === '\\',
): (filename: string | undefined) => string | undefined {
const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath

return (filename: string | undefined) => {
if (!filename) {
return
}

const normalizedFilename = isWindows ? normalizeWindowsPath(filename) : filename

// eslint-disable-next-line prefer-const
let { dir, base: file, ext } = posix.parse(normalizedFilename)

if (ext === '.js' || ext === '.mjs' || ext === '.cjs') {
file = file.slice(0, ext.length * -1)
}

if (!dir) {
// No dirname whatsoever
dir = '.'
}

const n = dir.lastIndexOf('/node_modules')
if (n > -1) {
return `${dir.slice(n + 14).replace(/\//g, '.')}:${file}`
}

// Let's see if it's a part of the main module
// To be a part of main module, it has to share the same base
if (dir.startsWith(normalizedBase)) {
let moduleName = dir.slice(normalizedBase.length + 1).replace(/\//g, '.')

if (moduleName) {
moduleName += ':'
}
moduleName += file

return moduleName
}

return file
}
}
108 changes: 108 additions & 0 deletions packages/modules/edge-api-sdk/src/sentry/sentry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import { createGetModuleFromFilename } from './module'

import { createEventEnvelope, getEnvelopeEndpointWithUrlEncodedAuth } from '@sentry/core'
import {
stackParserFromStackParserOptions,
createStackParser,
nodeStackLineParser,
exceptionFromError,
dsnFromString,
} from '@sentry/utils'

import { Envelope, SeverityLevel } from '@sentry/types'

import { LogLevel, LogPayload, MinimalLogPayload, Transport } from '../logger'

const encodeUTF8 = (input: string) => new TextEncoder().encode(input)

export function serializeEnvelope(envelope: Envelope): string | Uint8Array {
const [envHeaders, items] = envelope

// Initially we construct our envelope as a string and only convert to binary chunks if we encounter binary data
let parts: string | Uint8Array[] = JSON.stringify(envHeaders)

function append(next: string | Uint8Array): void {
if (typeof parts === 'string') {
parts = typeof next === 'string' ? parts + next : [encodeUTF8(parts), next]
} else {
parts.push(typeof next === 'string' ? encodeUTF8(next) : next)
}
}

for (const item of items) {
const [itemHeaders, payload] = item

append(`\n${JSON.stringify(itemHeaders)}\n`)

if (typeof payload === 'string' || payload instanceof Uint8Array) {
append(payload)
} else {
append(JSON.stringify(payload))
}
}

return typeof parts === 'string' ? parts : concatBuffers(parts)
}

function concatBuffers(buffers: Uint8Array[]): Uint8Array {
const totalLength = buffers.reduce((acc, buf) => acc + buf.length, 0)

const merged = new Uint8Array(totalLength)
let offset = 0
for (const buffer of buffers) {
merged.set(buffer, offset)
offset += buffer.length
}

return merged
}

const stackParser = stackParserFromStackParserOptions(
createStackParser(nodeStackLineParser(createGetModuleFromFilename())),
)

export type InitProps = {
dsn: string
environment?: string
release?: string
}

const logLevelToSeverityLevel = (logLevel: LogLevel): SeverityLevel => {
if (logLevel === 'panic' || logLevel === 'critical') {
return 'fatal'
}
return logLevel
}

export const init = (props: InitProps): Transport => {
const components = dsnFromString(props.dsn)
if (!components) {
throw new Error('invalid DSN provided')
}

return async (payload: MinimalLogPayload | LogPayload) => {
const errorEntry = payload.entries.find((entry) => !!entry.error)
const exception = errorEntry?.error ? exceptionFromError(stackParser, errorEntry.error) : undefined
const envelope = createEventEnvelope({
exception: exception
? {
values: [exception],
}
: undefined,
timestamp: errorEntry?.timestamp.getTime(),
breadcrumbs: payload.entries.map((entry) => {
return {
level: logLevelToSeverityLevel(entry.level),
message: entry.message,
timestamp: entry.timestamp.getTime(),
}
}),
})

const endpoint = getEnvelopeEndpointWithUrlEncodedAuth(components)
await fetch(endpoint, {
body: serializeEnvelope(envelope),
method: 'post',
})
}
}

0 comments on commit dd846a3

Please sign in to comment.