Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: axiom logs #28

Open
wants to merge 4 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions apps/admin/next.config.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require('path');
const { withSentryConfig } = require('@sentry/nextjs');
const { withAxiom } = require('next-axiom');

/** @type {import('next').NextConfig} */
const nextConfig = {
const nextConfig = withAxiom({
reactStrictMode: true,
transpilePackages: ['@avila-tek/ui'],
output: 'standalone',
experimental: {
outputFileTracingRoot: path.join(__dirname, '../../'),
serverComponentsExternalPackages: [],
},
};
});

const sentryWebpackPluginOptions = {
silent: true, // Suppresses all logs
Expand Down
6 changes: 6 additions & 0 deletions apps/admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
"name": "admin",
"version": "1.0.0",
"private": true,
"browser": {
"fs": false,
"path": false,
"os": false
},
"scripts": {
"dev": "next dev -p 3002",
"build": "next build",
Expand All @@ -26,6 +31,7 @@
"nanoid": "^4.0.2",
"next": "^13.4.4",
"next-auth": "^4.22.1",
"next-axiom": "^1.3.0",
"nprogress": "^0.2.0",
"react": "18.2.0",
"react-dom": "18.2.0",
Expand Down
13 changes: 13 additions & 0 deletions apps/admin/src/app/api/hello/route.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
export async function GET(request: Request) {
return new Response('Hello, Next.js!');
}

// import { withAxiom, AxiomRequest } from 'next-axiom';
// import { NextResponse } from 'next/server';

// export const GET = withAxiom((req: AxiomRequest) => {
// req.log.info('Hello function called');

// // You can create intermediate loggers
// const log = req.log.with({ scope: 'user' });
// log.info('User logged in', { userId: 42 });

// return new NextResponse('Hello, Next.js!');
// });
7 changes: 7 additions & 0 deletions apps/admin/src/components/UserList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@ import {
useQuery,
useSuspenseQuery,
} from '@apollo/experimental-nextjs-app-support/ssr';
import { useLog } from '@avila-tek/ui/src/utils/log';

export default function UserList() {
useLog({
message: 'Hello from UserList',
source: 'UserList.tsx',
userEmail: '[email protected]',
userId: 'exampleUserId',
});
const { data } = useQuery(gql`
query GET_USERS {
users {
Expand Down
16 changes: 16 additions & 0 deletions apps/admin/src/middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Logger } from 'next-axiom';
import { NextResponse } from 'next/server';
import type { NextFetchEvent, NextRequest } from 'next/server';

export async function middleware(request: NextRequest, event: NextFetchEvent) {
// ! Note: Should consider remove this loggers because spend storage
const logger = new Logger({
source: 'admin.middleware',
}); // traffic, request
logger.middleware(request);

event.waitUntil(logger.flush());
return NextResponse.next();
}
// For more information, see Matching Paths below
export const config = {};
1 change: 1 addition & 0 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"@apollo/utils.keyvaluecache": "^3.0.0",
"@aws-sdk/client-s3": "^3.341.0",
"@aws-sdk/s3-request-presigner": "^3.341.0",
"@axiomhq/js": "^1.0.0",
"@sentry/integrations": "^7.53.1",
"@sentry/node": "^7.53.1",
"@sentry/tracing": "^7.53.1",
Expand Down
8 changes: 8 additions & 0 deletions apps/api/src/components/axiom/axiom.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Type to create a log with Axiom
export type TCreateLog = {
message: string;
source: string;
userId?: string;
userEmail?: string;
error?: Error;
};
60 changes: 60 additions & 0 deletions apps/api/src/components/axiom/axiom.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Axiom } from '@axiomhq/js';
import { TCreateLog } from './axiom.dto';

function generateCleanStackTrace(error: Error): string[] {
// Condense stack trace to an array of strings (more readable)
let stack = error.stack?.split('\n').map((line) => line.trim()) || [];
// Remove the first line of the stack trace (it's the error message, which we already declare in title)
stack.shift();
// Remove project path from stack trace (makes it more readable)
const root = process.cwd();
stack = stack.map((line) => {
// Remove the "at" at the beginning of each line
const stackLine = line.slice(3);
// Compare case-insensitive but replace with original case
const rootIndex = stackLine.toLowerCase().indexOf(root.toLowerCase());
// If root path is not found, return original line
if (rootIndex === -1) return stackLine;
// Replace root path with empty string
return (
stackLine.slice(0, rootIndex) + stackLine.slice(rootIndex + root.length)
);
});
return stack;
}

/**
* Asynchronously logs a message to Axiom.
*
* This function takes a `TCreateLog` object containing the message details and sends it to Axiom using the `axiom` library.
* It expects the `AXIOM_TOKEN` and `AXIOM_ORG_ID` environment variables to be set with your Axiom credentials.
*
* @param {TCreateLog} args - An object containing the log message details.
* @example
* ```javascript
* const logEntry = {
* message: 'An error occurred',
* source: 'MyService',
* userId: '12345',
* userEmail: '[email protected]',
* };
*
* log(logEntry)
* ```
*/
export async function log(args: TCreateLog) {
try {
const axiom = new Axiom({
token: process.env.AXIOM_TOKEN,
orgId: process.env.AXIOM_ORG_ID,
});
axiom.ingest(process.env.AXIOM_DATASET, [
{
...args,
stack: args.error == null ? null : generateCleanStackTrace(args.error),
},
]);
} catch (error) {
console.error(error);
}
}
19 changes: 18 additions & 1 deletion apps/api/src/components/user/user/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type {
QueryOptions,
UpdateQuery,
} from 'mongoose';
import { log } from '../../axiom/axiom.service';
import { DniTypeEnum, IUser, User, UserTypeEnum } from './user.model';
import { paginateModel } from '../../../utils';

Expand All @@ -20,7 +21,23 @@ export async function find(
projection?: ProjectionType<IUser> | null,
options?: QueryOptions<IUser> | null
) {
return User.find(filter, projection, options).exec();
try {
log({
message: 'Message',
source: 'userService.find',
userEmail: '[email protected]',
userId: 'userId',
});
return User.find(filter, projection, options).exec();
} catch (error) {
log({
message: 'Error find user',
source: 'userService.find',
userEmail: '[email protected]',
userId: 'userId',
error,
});
}
}

export async function pagination(
Expand Down
5 changes: 3 additions & 2 deletions apps/client/next.config.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require('path');
const { withSentryConfig } = require('@sentry/nextjs');
const { withAxiom } = require('next-axiom');

/** @type {import('next').NextConfig} */
const nextConfig = {
const nextConfig = withAxiom({
reactStrictMode: true,
transpilePackages: ['@avila-tek/ui'],
output: 'standalone',
experimental: {
outputFileTracingRoot: path.join(__dirname, '../../'),
serverComponentsExternalPackages: [],
},
};
});

const sentryWebpackPluginOptions = {
silent: true, // Suppresses all logs
Expand Down
6 changes: 6 additions & 0 deletions apps/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
"name": "client",
"version": "1.0.0",
"private": true,
"browser": {
"fs": false,
"path": false,
"os": false
},
"scripts": {
"dev": "next dev -p 3001",
"build": "next build",
Expand All @@ -26,6 +31,7 @@
"nanoid": "^4.0.2",
"next": "^13.4.4",
"next-auth": "^4.22.1",
"next-axiom": "^1.3.0",
"nprogress": "^0.2.0",
"react": "18.2.0",
"react-dom": "18.2.0",
Expand Down
7 changes: 7 additions & 0 deletions apps/client/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { Inter } from 'next/font/google';
import { serverLog } from '@avila-tek/ui/src/utils/log';

const inter = Inter({ subsets: ['latin'] });

export default function Home() {
serverLog({
message: 'Hello Avila from HomePage',
source: 'HomePage',
userId: 'lesanpi',
});

return <main className={inter.className}>Home page</main>;
}
19 changes: 19 additions & 0 deletions apps/client/src/middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Logger } from 'next-axiom';
import { NextResponse } from 'next/server';
import type { NextFetchEvent, NextRequest } from 'next/server';

export async function middleware(request: NextRequest, event: NextFetchEvent) {
// ! Note: Should consider remove this loggers because spend storage
const logger = new Logger({
source: 'client.middleware',
args: {
msg: 'Message from middleware',
},
}); // traffic, request
logger.middleware(request);

event.waitUntil(logger.flush());
return NextResponse.next();
}
// For more information, see Matching Paths below
export const config = {};
Loading