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

Route path URL is undefined #40

Open
askareija opened this issue Jan 7, 2025 · 7 comments
Open

Route path URL is undefined #40

askareija opened this issue Jan 7, 2025 · 7 comments
Labels
bug Something isn't working

Comments

@askareija
Copy link

What version of Elysia is running?

1.2.10

What platform is your computer?

Linux 6.9.3-76060903-generic x86_64 unknown

What steps can reproduce the bug?

  1. Call a route
  2. Check tracing backend (I'm using Jaeger)
  3. You will see "GET undefined" for route path

What is the expected behavior?

route path is not undefined.

What do you see instead?

gambar

gambar

Additional information

Packages installed:

Opentelemetry middleware:

import { opentelemetry } from '@elysiajs/opentelemetry';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-node';
import Elysia from 'elysia';
import { OTLP_TRACE_ENDPOINT, OTLP_TRACE_TOKEN } from '../constants';
import { MongooseInstrumentation } from '@opentelemetry/instrumentation-mongoose';
import { PinoInstrumentation } from '@opentelemetry/instrumentation-pino';

const otelMiddleware = new Elysia({
    name: 'opentelemetry-middleware',
}).use(opentelemetry({
    serviceName: 'main-backend',
    instrumentations: [
        new MongooseInstrumentation(),
        new PinoInstrumentation(),
    ],
    spanProcessors: [
        new BatchSpanProcessor(new OTLPTraceExporter({
            url: `${OTLP_TRACE_ENDPOINT}`,
            // headers: {
            //     Authorization: `Bearer ${OTLP_TRACE_TOKEN}`,
            // }
        }))
    ]
}));

export default otelMiddleware;

Main elysia:

const app = new Elysia()
    .use(
        cors({
            methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
            origin: ALLOWED_ORIGINS,
        }),
    )
    // SECTION: Use OpenTelemetry middleware
    .use(otelMiddleware)
    // !SECTION

    // SECTION: Importing controllers
    .use(usersController);

if (!IS_PRODUCTION) {
    app.use(swagger());
}

usersController:

const userService = new UserService();

const usersController = new Elysia({
    name: 'users-controller',
    prefix: '/users',
});

usersController
    .get('/', async ({ query }) => {
        const page = Number(query?.page) || 1;
        const limit = Number(query?.limit) || 10;
        return await record('getUsers', () => userService.getUsers(page, limit));
    })
    .post('/', async ({ body }) => {
        return await userService.createUser(body);
    })
    .get('/:id', async ({ params: { id } }) => {
        return await userService.getUserById(id);
    })
    .put('/:id', async ({ params: { id }, body }) => {
        return await userService.updateUser(id, body);
    })
    .delete('/:id', async ({ params: { id } }) => {
        return await userService.deleteUser(id);
    });

export default usersController;

Have you try removing the node_modules and bun.lockb and try again yet?

yes

@askareija askareija added the bug Something isn't working label Jan 7, 2025
@askareija
Copy link
Author

gambar

looks like http.route tag is not defined

@johnny-woodtke
Copy link

I'm also having this issue since upgrading to Elysia 1.2 from 1.1. I'm using Sentry as my tracing backend.

@johnny-woodtke
Copy link

johnny-woodtke commented Jan 11, 2025

@askareija I've noticed in my Elysia server that the routes in my traces are defined once I place my opentelemetry plugin before cors plugin, and remove my swagger and staticPlugin.

I think there's some sort of interaction occurring between the cors and swagger plugins because the route appears in the traces when I remove cors and leave in swagger or vice-versa.

EDIT: After thinking about it a bit more, there is likely an interaction occurring between cors and whenever Elysia is serving static files (such as OpenAPI JSON served by swagger, or any files served by the staticPlugin).

@askareija
Copy link
Author

OK thanks for the info, i've tried to move opentelemetry plugin before cors, and try to disable my swagger plugin but it's still didn't work. still got undefined.

@askareija
Copy link
Author

i make it working by calling "route" property. Steps like this:

Create a logging middleware and run it on onAfterResponse lifecycle, then call the route like this:

import Elysia from 'elysia';
import { logger } from '../logger';
import { record } from '@elysiajs/opentelemetry';

const loggingMiddleware = new Elysia().onAfterResponse(
   { as: 'scoped' },
   ({ request, set, server, path, route }) => {
       record('middleware.logging.log_request', () => {
           const status = set.status as number;
           console.log("Route: ", route);
           const ip_address = server?.requestIP(request)?.address;
           logger[status >= 400 ? 'error' : 'info'](
               { ip_address },
               `${request.method}: ${path} - ${set.status}`,
           );
       });
   },
);

export default loggingMiddleware;

and then call it in main instance:

const app = new Elysia({
    precompile: true,
})
    // SECTION: Middleware sections
    .use(
        cors({
            methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
            origin: ALLOWED_ORIGINS,
        }),
    )
    .use(otelMiddleware)
    .use(loggingMiddleware)
    // !SECTION

    // SECTION: Import controller dengan lazy loading
    .use(import('../users/user_controller'))
    .get('/roles', () => "Roles route.")

if (!IS_PRODUCTION) {
    app.use(swagger());
}

export default app;

Yea i'm using OTLPLogExporter and pino for logging the server.

As you can see from the picture below, route path is now defined and even i see the "client.address" span attributes. which i never seen it before.

gambar

@johnny-woodtke
Copy link

Great find! Using that onAfterResponse pattern worked for me as well.

Interestingly enough, I only had to reference the route for it to be injected into my spans:

Screenshot 2025-01-12 at 12 10 22 PM

@askareija
Copy link
Author

Cool!, looks like work around for this is injecting attributes on after response 🥴

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants