Skip to content

Commit

Permalink
feat: move away from opentelemetry
Browse files Browse the repository at this point in the history
The current setup with OpenTelemetry sucks because no data is being emitted anywhere. So I think it'd be best if we revert all that and just use plain Sentry with their built-in performance integration.
  • Loading branch information
aldy505 committed Mar 29, 2024
1 parent 70c2373 commit d38c6cb
Show file tree
Hide file tree
Showing 14 changed files with 274 additions and 744 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ ENV PORT=3000

EXPOSE ${PORT}

CMD [ "node", "--import", "./dist/src/tracing.js", "./dist/src/index.js" ]
CMD ["node", "./dist/src/index.js"]
1 change: 1 addition & 0 deletions env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ declare global {
DEV_PROXY_URL: string;
PORT: string;
IGNORE_PRIVATE_REPOSITORY?: string
SENTRY_DSN?: string;
}
}
}
Expand Down
10 changes: 1 addition & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"main": "dist/index.js",
"type": "module",
"scripts": {
"dev:start": "node --experimental-loader @esbuild-kit/esm-loader --env-file .env -r src/tracing.ts src/index.ts",
"dev:start": "node --experimental-loader @esbuild-kit/esm-loader --env-file .env src/index.ts",
"dev": "nodemon -e ts --watch src --exec \"npm run dev:start\"",
"build": "tsc && tsc-alias",
"test:unit": "vitest run",
Expand Down Expand Up @@ -49,15 +49,7 @@
"dependencies": {
"@hono/node-server": "^1.8.0",
"@octokit/webhooks-types": "^7.3.2",
"@opentelemetry/api": "^1.7.0",
"@opentelemetry/context-async-hooks": "^1.21.0",
"@opentelemetry/exporter-trace-otlp-grpc": "^0.48.0",
"@opentelemetry/instrumentation-http": "^0.48.0",
"@opentelemetry/sdk-metrics": "^1.21.0",
"@opentelemetry/sdk-node": "^0.48.0",
"@opentelemetry/sdk-trace-node": "^1.21.0",
"@sentry/node": "^7.101.1",
"@sentry/opentelemetry": "^7.101.1",
"cheerio": "1.0.0-rc.12",
"colorette": "^2.0.20",
"eventsource": "^2.0.2",
Expand Down
548 changes: 18 additions & 530 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

14 changes: 8 additions & 6 deletions src/application/adapters/GithubAdapter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { WebhookEvent } from "@octokit/webhooks-types";
import { trace } from "@opentelemetry/api";
import * as Sentry from "@sentry/node";

Check warning on line 2 in src/application/adapters/GithubAdapter.ts

View check run for this annotation

Codecov / codecov/patch

src/application/adapters/GithubAdapter.ts#L2

Added line #L2 was not covered by tests
import type {
Comment,
CommentChanges,
Expand All @@ -14,8 +14,6 @@ import type {
WebhookEventName
} from "~/application/webhook/types";

const tracer = trace.getTracer("application.adaptersGithubAdapter");

export class GithubAdapter {
private readonly _repository?: Repository;
private readonly _issue?: Issue;
Expand Down Expand Up @@ -137,9 +135,13 @@ export class GithubAdapter {
}

get(eventName: WebhookEventName) {
return tracer.startActiveSpan("get", (span) => {
span.setAttribute("event_name", eventName);

return Sentry.startSpan({
name: "get",
op: "application.adaptersGithubAdapter",
attributes: {
"event_name": eventName
}
}, () => {

Check warning on line 144 in src/application/adapters/GithubAdapter.ts

View check run for this annotation

Codecov / codecov/patch

src/application/adapters/GithubAdapter.ts#L138-L144

Added lines #L138 - L144 were not covered by tests
// issue related events
if (eventName.startsWith("issue")) {
const payload = {
Expand Down
32 changes: 23 additions & 9 deletions src/application/webhook/GithubWebhook.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { createHmac, timingSafeEqual } from "node:crypto";
import type { WebhookEvent } from "@octokit/webhooks-types";
import { trace } from "@opentelemetry/api";
import * as Sentry from "@sentry/node";

Check warning on line 3 in src/application/webhook/GithubWebhook.ts

View check run for this annotation

Codecov / codecov/patch

src/application/webhook/GithubWebhook.ts#L3

Added line #L3 was not covered by tests
import { GithubAdapter } from "../adapters/GithubAdapter";
import type { ILogger } from "../interfaces/ILogger";
import type { HandlerFunction, IWebhook, WebhookEventName } from "./types";
import { IGNORE_PRIVATE_REPOSITORY } from "~/env";

const tracer = trace.getTracer("application.webhook.GithubWebhook");

export class GithubWebhook implements IWebhook<WebhookEvent> {
public readonly secretToken: string;
private readonly _handlers: Partial<Record<WebhookEventName, HandlerFunction<WebhookEventName>[]>> = {};
Expand All @@ -20,7 +18,10 @@ export class GithubWebhook implements IWebhook<WebhookEvent> {
}

public verify(payload: string, signature: string) {
return tracer.startActiveSpan("verify", async () => {
return Sentry.startSpan({
name: "verify",
op: "application.webhook.GithubWebhook"
}, async () => {

Check warning on line 24 in src/application/webhook/GithubWebhook.ts

View check run for this annotation

Codecov / codecov/patch

src/application/webhook/GithubWebhook.ts#L21-L24

Added lines #L21 - L24 were not covered by tests
if (payload.length === 0 || signature.length === 0) throw Error("payload or signature wasn't provided.");

const signatureBuffer = Buffer.from(signature);
Expand All @@ -35,15 +36,23 @@ export class GithubWebhook implements IWebhook<WebhookEvent> {
}

public sign(payload: string): Promise<string> {
return tracer.startActiveSpan("sign", () => {
return Sentry.startSpan({
name: "sign",
op: "application.webhook.GithubWebhook"
}, () => {

Check warning on line 42 in src/application/webhook/GithubWebhook.ts

View check run for this annotation

Codecov / codecov/patch

src/application/webhook/GithubWebhook.ts#L39-L42

Added lines #L39 - L42 were not covered by tests
if (payload.length === 0) throw Error("payload wasn't provided.");
return Promise.resolve(`sha256=${createHmac("sha256", this.secretToken).update(payload).digest("hex")}`);
});
}

public on<E extends WebhookEventName>(event: E, handler: HandlerFunction<E>): void {
return tracer.startActiveSpan("on", (span) => {
span.setAttribute("event", event);
return Sentry.startSpan({
name: "on",
op: "application.webhook.GithubWebhook",
attributes: {
event: event
}
}, () => {

Check warning on line 55 in src/application/webhook/GithubWebhook.ts

View check run for this annotation

Codecov / codecov/patch

src/application/webhook/GithubWebhook.ts#L49-L55

Added lines #L49 - L55 were not covered by tests
if (this._handlers[event] === undefined) {
this._handlers[event] = [];
}
Expand All @@ -52,8 +61,13 @@ export class GithubWebhook implements IWebhook<WebhookEvent> {
}

public handle(eventName: WebhookEventName, payload: WebhookEvent, targetsId: bigint[]): Promise<void> {
return tracer.startActiveSpan("handle", async (span) => {
span.setAttribute("event_name", eventName);
return Sentry.startSpan({
name: "handle",
op: "application.webhook.GithubWebhook",
attributes: {
"event_name": eventName
}
}, async () => {

Check warning on line 70 in src/application/webhook/GithubWebhook.ts

View check run for this annotation

Codecov / codecov/patch

src/application/webhook/GithubWebhook.ts#L64-L70

Added lines #L64 - L70 were not covered by tests
const handlers = this._handlers[eventName] as HandlerFunction<WebhookEventName>[];

// no handler available
Expand Down
18 changes: 16 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import path from "path";
import { Bot } from "grammy";
import { parse as parseGura } from "gura";
import { Hono } from "hono";
import { otelTracer } from "./utils/honoOtelTracer";
import * as Sentry from "@sentry/node";
import { sentryMiddleware } from "./utils/honoSentryTracer";

Check warning on line 7 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L6-L7

Added lines #L6 - L7 were not covered by tests
import { appConfigSchema } from "~/schema";
import { BOT_TOKEN, GITHUB_WEBHOOK_SECRET, PORT, HOME_GROUP } from "~/env";
import { InMemoryGroupMapping } from "~/infrastructure/InMemoryGroupMapping";
Expand All @@ -22,6 +23,15 @@ import { GithubRoute } from "~/presentation/routes/GithubRoute";
import { GithubWebhook } from "~/application/webhook/GithubWebhook";
import { TelegramPresenter } from "~/presentation/TelegramPresenter";

Sentry.init({
dsn: process.env.SENTRY_DSN ?? "",
sampleRate: 1.0,
tracesSampleRate: 0.3,
integrations: [
Sentry.httpIntegration({ tracing: true })
]
});

Check warning on line 34 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L26-L34

Added lines #L26 - L34 were not covered by tests
// configurations
const configFile = await readFile(path.resolve("config", "config.ura"), { encoding: "utf-8" });
const config = appConfigSchema.parse(parseGura(configFile));
Expand Down Expand Up @@ -56,7 +66,11 @@ const eventHandlers: EventHandlerMapping = {
// webhook server and handlers
const serverInstance = new Hono();
serverInstance.get("/", (c) => c.text("OK"));
serverInstance.use("*", otelTracer("gitgram"));
serverInstance.use(sentryMiddleware());
serverInstance.onError((_, c) => {
c.status(500);
return c.json({ message: "Internal server error" });
});

Check warning on line 73 in src/index.ts

View check run for this annotation

Codecov / codecov/patch

src/index.ts#L69-L73

Added lines #L69 - L73 were not covered by tests
const githubRoute = new GithubRoute(serverInstance, {
path: "/github",
webhook: new GithubWebhook(GITHUB_WEBHOOK_SECRET, logger),
Expand Down
9 changes: 5 additions & 4 deletions src/presentation/event-handlers/Deployment.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { trace } from "@opentelemetry/api";
import * as Sentry from "@sentry/node";
import { z } from "zod";
import type { IDeploymentEvent } from "~/application/interfaces/events/IDeploymentEvent";
import type { IPresenter } from "~/application/interfaces/IPresenter";
import type { HandlerFunction } from "~/application/webhook/types";
import { interpolate } from "~/utils/interpolate";

const tracer = trace.getTracer("presentation.event-handlers.Deployment");

export const deploymentTemplateSchema = z.object({
status: z.object({
base: z.string(),
Expand All @@ -22,7 +20,10 @@ export class DeploymentEventHandler implements IDeploymentEvent {

status(): HandlerFunction<"deployment_status"> {
return (event) => {
return tracer.startActiveSpan("status", () => {
return Sentry.startSpan({
name: "status",
op: "presentation.event-handlers.Deployment"
}, () => {

Check warning on line 26 in src/presentation/event-handlers/Deployment.ts

View check run for this annotation

Codecov / codecov/patch

src/presentation/event-handlers/Deployment.ts#L23-L26

Added lines #L23 - L26 were not covered by tests
const description = event.payload.deploymentStatus.description;
const response = interpolate(
this._templates.status.statuses[event.payload.deploymentStatus.state.toLowerCase()] +
Expand Down
34 changes: 25 additions & 9 deletions src/presentation/event-handlers/Discussion.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { trace } from "@opentelemetry/api";
import * as Sentry from "@sentry/node";
import { z } from "zod";
import type { IPresenter } from "~/application/interfaces/IPresenter";
import type { IDiscussionEvent } from "~/application/interfaces/events/IDiscussionEvent";
import type { HandlerFunction } from "~/application/webhook/types";
import { interpolate } from "~/utils/interpolate";

const tracer = trace.getTracer("presentation.event-handlers.Discussion");

export const discussionTemplateSchema = z.object({
created: z.string().trim(),
closed: z.string().trim(),
Expand All @@ -27,7 +25,10 @@ export class DiscussionEventHandler implements IDiscussionEvent {

created(): HandlerFunction<"discussion.created"> {
return (event) => {
return tracer.startActiveSpan("created", () => {
return Sentry.startSpan({
name: "created",
op: "presentation.event-handlers.Discussion"
}, () => {
const message = this._templates.created;
const payload = interpolate(message, {
url: event.payload.discussion.url,
Expand All @@ -49,7 +50,10 @@ export class DiscussionEventHandler implements IDiscussionEvent {

closed(): HandlerFunction<"discussion.closed"> {
return (event) => {
return tracer.startActiveSpan("closed", () => {
return Sentry.startSpan({
name: "closed",
op: "presentation.event-handlers.Discussion"
}, () => {
const message = this._templates.closed;
const payload = interpolate(message, {
url: event.payload.discussion.url,
Expand All @@ -71,7 +75,10 @@ export class DiscussionEventHandler implements IDiscussionEvent {

reopened(): HandlerFunction<"discussion.reopened"> {
return (event) => {
return tracer.startActiveSpan("reopened", () => {
return Sentry.startSpan({
name: "reopened",
op: "presentation.event-handlers.Discussion"
}, () => {
const message = this._templates.reopened;
const payload = interpolate(message, {
url: event.payload.discussion.url,
Expand All @@ -93,7 +100,10 @@ export class DiscussionEventHandler implements IDiscussionEvent {

edited(): HandlerFunction<"discussion.edited"> {
return (event) => {
return tracer.startActiveSpan("edited", () => {
return Sentry.startSpan({
name: "edited",
op: "presentation.event-handlers.Discussion"
}, () => {
const message = this._templates.edited;
const payload = interpolate(message, {
url: event.payload.discussion.url,
Expand All @@ -115,7 +125,10 @@ export class DiscussionEventHandler implements IDiscussionEvent {

deleted(): HandlerFunction<"discussion.deleted"> {
return (event) => {
return tracer.startActiveSpan("deleted", () => {
return Sentry.startSpan({
name: "deleted",
op: "presentation.event-handlers.Discussion"
}, () => {
const message = this._templates.deleted;
const payload = interpolate(message, {
url: event.payload.discussion.url,
Expand All @@ -137,7 +150,10 @@ export class DiscussionEventHandler implements IDiscussionEvent {

pinned(): HandlerFunction<"discussion.pinned"> {
return (event) => {
return tracer.startActiveSpan("pinned", () => {
return Sentry.startSpan({
name: "pinned",
op: "presentation.event-handlers.Discussion"
}, () => {
const message = this._templates.pinned;
const payload = interpolate(message, {
url: event.payload.discussion.url,
Expand Down
Loading

0 comments on commit d38c6cb

Please sign in to comment.