#Creating http log handler

9 messages · Page 1 of 1 (latest)

sterile path
#

Hello everyone,

I'm looking to create a logger handler that sends logs to a remote endpoint using HTTP. I need the logger handler to have the following functionalities:

  • It should run in the background so that it does not affect the execution of the main program from the network request.
  • It should continue sending logs even if the execution of the main program is complete.

I wrote the following code:


type HttpLogHandler struct {
    endpoint     string
    requestQueue chan []byte
    httpClient   *http.Client
    waitGroup    sync.WaitGroup
}

func NewHttpLogHandler(endpoint string) *HttpLogHandler {
    requestQueue := make(chan []byte, 1000)
    httpClient := &http.Client{}

    h := &HttpLogHandler{
        endpoint:     endpoint,
        requestQueue: requestQueue,
        httpClient:   httpClient,
    }

    h.waitGroup.Add(1)
    go h.writeToEndpoint()

    return h
}

func (h *HttpLogHandler) writeToEndpoint() {
    defer h.waitGroup.Done()

    for data := range h.requestQueue {
        _, err := h.httpClient.Post(h.endpoint, "text/plain", bytes.NewReader(data))
        if err != nil {
            log.Printf("Error sending log data to endpoint: %v", err)
        }
    }
    h.waitGroup.Wait()

}

func (h *HttpLogHandler) Write(data []byte) (int, error) {
    h.requestQueue <- data
    return len(data), nil
}

This code currently fulfill the first requirement, but would not the second one. Anyone has any idea how do handle this?

inland sail
#

wdym by "main program is complete." ?

#

everything stop when main is complete. main is your program.

#

except, if the program that you want to monitor is run in different process.
like a supervisor, a program that monitor other program and send the information to other place.
but then, it wont be a logger anymore. it'd be a process manager or supervisor.

sterile path
#

I'll give an example:

Given the following snippet:

logHandler := goLogger.NewHttpLogHandler(endpoint)
logger := log.New(logHandler, "", log.Ltime)
logger.Println("Hello, world!")

Currently, the program terminates before the logger sends the input to the remote endpoint. I want to validate that the program would end only after sending this log.

warm delta
#

did you mean this situation that your main program crash?

if you just need to send all of your log to remote before your main program complete, you can check status at end of main program.

then just wait it finish.

inland sail
sterile path
inland sail
#

you can make the logger.Println to send the message to a channel and worker will send to http upstream in the background.