Skip to content

Commit

Permalink
feat: add sentry to achievements worker (#3640)
Browse files Browse the repository at this point in the history
* feat: add sentry to achievements worker

* feat: add RELEASE var
  • Loading branch information
bigint committed Aug 29, 2023
1 parent 5f6f941 commit 4c5044d
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 40 deletions.
1 change: 1 addition & 0 deletions packages/workers/achievements/.dev.vars.example
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
SENTRY_DSN=""
CLICKHOUSE_REST_ENDPOINT=""
6 changes: 4 additions & 2 deletions packages/workers/achievements/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
"prettier": "prettier --check \"**/*.{js,ts,tsx,md}\" --cache",
"prettier:fix": "prettier --write \"**/*.{js,ts,tsx,md}\" --cache",
"typecheck": "tsc --pretty",
"worker:deploy": "wrangler deploy"
"worker:deploy": "wrangler deploy --var RELEASE:\"$(git rev-parse HEAD)\""
},
"dependencies": {
"@lenster/data": "workspace:*",
"@lenster/lib": "workspace:*",
"itty-router": "^4.0.22"
"@sentry/tracing": "^7.65.0",
"itty-router": "^4.0.22",
"toucan-js": "^3.2.3"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20230821.0",
Expand Down
21 changes: 18 additions & 3 deletions packages/workers/achievements/src/handlers/hasUsedLenster.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
import '@sentry/tracing';

import { Errors } from '@lenster/data/errors';
import response from '@lenster/lib/response';

import type { Env } from '../types';
import type { WorkerRequest } from '../types';

export default async (request: WorkerRequest) => {
const transaction = request.sentry?.startTransaction({
name: '@lenster/achievements/hasUsedLenster'
});

const { id } = request.params;

export default async (id: string, env: Env) => {
if (!id) {
return response({ success: false, error: Errors.NoBody });
}

try {
const clickhouseRequestSpan = transaction?.startChild({
name: 'clickhouse-request'
});
const clickhouseResponse = await fetch(
`${env.CLICKHOUSE_REST_ENDPOINT}&default_format=JSONCompact`,
`${request.env.CLICKHOUSE_REST_ENDPOINT}&default_format=JSONCompact`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
cf: { cacheTtl: 600, cacheEverything: true },
body: `SELECT count(*) FROM events WHERE actor = '${id}';`
}
);
clickhouseRequestSpan?.finish();

if (clickhouseResponse.status !== 200) {
return response({ success: false, error: Errors.StatusCodeIsNot200 });
Expand All @@ -32,6 +44,9 @@ export default async (id: string, env: Env) => {
hasUsedLenster: parseInt(json.data[0][0]) > 0
});
} catch (error) {
request.sentry?.captureException(error);
throw error;
} finally {
transaction?.finish();
}
};
19 changes: 16 additions & 3 deletions packages/workers/achievements/src/handlers/streaksCalendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,25 @@ import response from '@lenster/lib/response';

import filteredEvents from '../helpers/filteredNames';
import generateDateRangeDict from '../helpers/generateDateRangeDict';
import type { Env } from '../types';
import type { WorkerRequest } from '../types';

export default async (request: WorkerRequest) => {
const transaction = request.sentry?.startTransaction({
name: '@lenster/achievements/streaksCalendar'
});

const { id } = request.params;

export default async (id: string, env: Env) => {
if (!id) {
return response({ success: false, error: Errors.NoBody });
}

try {
const clickhouseRequestSpan = transaction?.startChild({
name: 'clickhouse-request'
});
const clickhouseResponse = await fetch(
`${env.CLICKHOUSE_REST_ENDPOINT}&default_format=JSONCompact`,
`${request.env.CLICKHOUSE_REST_ENDPOINT}&default_format=JSONCompact`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
Expand All @@ -29,6 +38,7 @@ export default async (id: string, env: Env) => {
`
}
);
clickhouseRequestSpan?.finish();

if (clickhouseResponse.status !== 200) {
return response({ success: false, error: Errors.StatusCodeIsNot200 });
Expand All @@ -48,6 +58,9 @@ export default async (id: string, env: Env) => {

return response({ success: true, data: allDatesData });
} catch (error) {
request.sentry?.captureException(error);
throw error;
} finally {
transaction?.finish();
}
};
19 changes: 16 additions & 3 deletions packages/workers/achievements/src/handlers/streaksList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@ import { Errors } from '@lenster/data/errors';
import response from '@lenster/lib/response';

import filteredEvents from '../helpers/filteredNames';
import type { Env } from '../types';
import type { WorkerRequest } from '../types';

export default async (request: WorkerRequest) => {
const transaction = request.sentry?.startTransaction({
name: '@lenster/achievements/streaksList'
});

const { id, date } = request.params;

export default async (id: string, date: string, env: Env) => {
if (!id) {
return response({ success: false, error: Errors.NoBody });
}
Expand Down Expand Up @@ -33,15 +39,19 @@ export default async (id: string, date: string, env: Env) => {
};
`;

const clickhouseRequestSpan = transaction?.startChild({
name: 'clickhouse-request'
});
const clickhouseResponse = await fetch(
`${env.CLICKHOUSE_REST_ENDPOINT}&default_format=JSONCompact`,
`${request.env.CLICKHOUSE_REST_ENDPOINT}&default_format=JSONCompact`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
cf: { cacheTtl: 600, cacheEverything: true },
body: query
}
);
clickhouseRequestSpan?.finish();

if (clickhouseResponse.status !== 200) {
return response({ success: false, error: Errors.StatusCodeIsNot200 });
Expand All @@ -62,6 +72,9 @@ export default async (id: string, date: string, env: Env) => {
})
});
} catch (error) {
request.sentry?.captureException(error);
throw error;
} finally {
transaction?.finish();
}
};
20 changes: 20 additions & 0 deletions packages/workers/achievements/src/helpers/buildRequest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { Toucan } from 'toucan-js';

import type { Env, WorkerRequest } from '../types';

const buildRequest = (
request: Request,
env: Env,
ctx: ExecutionContext,
sentry?: Toucan
): WorkerRequest => {
const temp: WorkerRequest = request as WorkerRequest;
temp.req = request;
temp.env = env;
temp.ctx = ctx;
temp.sentry = sentry;

return temp;
};

export default buildRequest;
71 changes: 42 additions & 29 deletions packages/workers/achievements/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { createCors, error, json, Router } from 'itty-router';
import { Errors } from '@lenster/data/errors';
import response from '@lenster/lib/response';
import { createCors, error, Router, status } from 'itty-router';
import { Toucan } from 'toucan-js';

import hasUsedLenster from './handlers/hasUsedLenster';
import streaksCalendar from './handlers/streaksCalendar';
import streaksList from './handlers/streaksList';
import type { Env } from './types';
import buildRequest from './helpers/buildRequest';
import type { Env, WorkerRequest } from './types';

const { preflight, corsify } = createCors({
origins: ['*'],
Expand All @@ -12,34 +16,43 @@ const { preflight, corsify } = createCors({

const router = Router();

router.all('*', preflight);
router.get('/', () => new Response('gm, to achievements service 👋'));
router.get('/hasUsedLenster/:id', ({ params }, env) =>
hasUsedLenster(params.id, env)
);
router.get('/streaks/:id', ({ params }, env) =>
streaksCalendar(params.id, env)
);
router.get('/streaks/:id/:date', ({ params }, env) =>
streaksList(params.id, params.date, env)
);
router
.all('*', preflight)
.head('*', () => status(200))
.get('/', (request: WorkerRequest) =>
response({
message: 'gm, to achievements service 👋',
version: request.env.RELEASE ?? 'unknown'
})
)
.get('/hasUsedLenster/:id', (request: WorkerRequest) =>
hasUsedLenster(request)
)
.get('/streaks/:id', (request: WorkerRequest) => streaksCalendar(request))
.get('/streaks/:id/:date', (request: WorkerRequest) => streaksList(request))
.all('*', () => error(404));

const routerHandleStack = (request: Request, env: Env, ctx: ExecutionContext) =>
router.handle(request, env, ctx).then(json);
export default {
async fetch(
request: Request,
env: Env,
ctx: ExecutionContext
): Promise<Response> {
const sentry = new Toucan({
request,
context: ctx,
tracesSampleRate: 1.0,
dsn: env.SENTRY_DSN,
release: env.RELEASE
});
const incomingRequest = buildRequest(request, env, ctx, sentry);

const handleFetch = async (
request: Request,
env: Env,
ctx: ExecutionContext
) => {
try {
return await routerHandleStack(request, env, ctx);
} catch {
return error(500);
return await router
.handle(incomingRequest)
.then(corsify)
.catch((error_) => {
sentry.captureException(error_);
return error(500, Errors.InternalServerError);
});
}
};

export default {
fetch: (request: Request, env: Env, context: ExecutionContext) =>
handleFetch(request, env, context).then(corsify)
};
12 changes: 12 additions & 0 deletions packages/workers/achievements/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
import type { IRequestStrict } from 'itty-router';
import type { Toucan } from 'toucan-js';

export interface Env {
SENTRY_DSN: string;
RELEASE: string;
CLICKHOUSE_REST_ENDPOINT: string;
}

export type WorkerRequest = {
req: Request;
env: Env;
ctx: ExecutionContext;
sentry?: Toucan;
} & IRequestStrict;
2 changes: 2 additions & 0 deletions packages/workers/achievements/wrangler.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ routes = [
mode = "smart"

[env.production.vars]
SENTRY_DSN = ""
RELEASE = ""
CLICKHOUSE_REST_ENDPOINT = ""
6 changes: 6 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 comments on commit 4c5044d

@vercel
Copy link

@vercel vercel bot commented on 4c5044d Aug 29, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

prerender – ./apps/prerender

prerender-lenster.vercel.app
prerender-git-main-lenster.vercel.app
prerender.lenster.xyz

@vercel
Copy link

@vercel vercel bot commented on 4c5044d Aug 29, 2023

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

web – ./apps/web

lenster.vercel.app
web-lenster.vercel.app
web-git-main-lenster.vercel.app
lenster.xyz

Please sign in to comment.