Code Monkey home page Code Monkey logo

Comments (6)

yusukebe avatar yusukebe commented on September 2, 2024 2

Hi @rafaell-lycan,

To handle Node.js specific matters, I'm considering passing IncomingMessage as part of the Bindings in @hono/node-server. This way, you can access it with c.env.IncomingMessage:

import { Hono } from 'hono'
import { serve } from '@hono/node-server'
import { IncomingMessage } from 'http'

type Bindings = {
  IncomingMessage: IncomingMessage
}

const app = new Hono<{ Bindings: Bindings }>()

app.get('/', (c) => {
  return c.text(`You access from ${c.env.IncomingMessage.socket.remoteAddress}`)
})

serve(app)

With access to IncomingMessage, I think you can create a logger similar to morgan.

from node-server.

yusukebe avatar yusukebe commented on September 2, 2024 1

Hi @rafaell-lycan

I think you can do it. I think you can declare that middleware on top of the handlers/middleware.

The following Logger middleware implementation would be helpful:

https://github.com/honojs/hono/blob/main/src/middleware/logger/index.ts

from node-server.

rafaell-lycan avatar rafaell-lycan commented on September 2, 2024

@yusukebe I'm not sure if this would work on this scenario.

Consider it as a middleware that acts after the route resolution.

(request) -> [middleware] -> (route match) -> [handler] -> (event)

How this implementation would look like? I was digging a bit on this pkg implementation but I haven't found where we could potentially create a mediator/event-dispatcher for it (probably on Hono's core).

I believe this could be a simple feature that can be enabled/disabled at the config level.

import { Hono, MiddlewareHandler } from 'hono'
import { serve } from '@hono/node-server'

// It could be always enabled when used with `@hono/node-server` 
// and optional (different implementation) for Edge.
const app = new Hono({ enableEvents: true })

const eventLoggerMiddleware = (): MiddlewareHandler => async (ctx, next) => {
  // Available with Context
  ctx.on('finish', () => {
    // Magic goes here.
  })
  
  await next()
}

// OR with custom events `onEvent` with Hono
app.onFinished((ctx) => {
  // Magic goes here.
})

app.use('*', eventLoggerMiddleware())
app.get('/', (ctx) => {
  return ctx.text('My shining new API')
})

serve(app)

from node-server.

rafaell-lycan avatar rafaell-lycan commented on September 2, 2024

@yusukebe any ideas if this will be supported or any workaround to make it work?

from node-server.

yusukebe avatar yusukebe commented on September 2, 2024

@rafaell-lycan

I'm not super familiar with Node.js. The mental model of Node.js is different from the Web Standard API used by Cloudflare Workers and others. These runtimes don't use the timing like a finish. So, I might not yet fully understand it.

I think you already know it, but f it is only to be executed at the very end, you can write this:

const app = new Hono()

app.use(async (c, next) => {
  await next()
  // logging
})

app.get('/', (c) => c.json('handler'))

Or, with PR #129, you can now take the IncomingMessage from c.env and use that.

from node-server.

rafaell-lycan avatar rafaell-lycan commented on September 2, 2024

@yusukebe what I'm trying to accomplish is essentially migrate a few middleware (Express) which calculates the total time of the request and send the data to my metrics collector (OTL/Datadog) later.

Implementation-wise you imagine the following scenario:

  • You add a middleware which will collect all the data you need;
  • On every request, the middleware sets defines a requestId and startAt used later to calculate how long the full request took to complete including the request status (SLA/SLO control), path, user-agent and a few other bits

Would this be possible?

app.use(async (c, next) => {
  const startTime = performance.now()
  const requestId = c.req.header('x-request-id') ?? uuid()
  
  await next()
  
  const tags = {
    ...getContextTags(), // additional tags from an AsyncLocalStorage
    request_id: requestId,
    path: c.req.routePath,
    "user-agent": c.req.header('User-Agent'),
    method: c.req.method,
    // HTTP Code - No idea how to retrieve this | Express: res.statusCode.toString()
    response_code: c.res.status // ?,
  }
  
  const duration = Math.floor(performance.now() - startTime)
  collector.timing('http.request_latency', duration, tags)
})

app.get('/', (c) => c.json('handler'))

from node-server.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.