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
questions for session base logging #88
Comments
Hi chy168! I think that in most cases, the scenario 3.2 should work for you. Check the App Engine integration section for an example. There is no ReplaceLogger and each logger goes as a variable (exactly what you need), so there won't be any conflicts/incorrect ids. However, the scenario 3.2 and the AppEngine example is written this way because logging to AppEngine required passing the appengine.Context. But, if in your case you just need to output the session id, then I recommend you to think about a far more simple and convenient solution: just create your own struct, that contains seelog.LoggerInterface field and a session id field. Then you can override the Trace/Tracef, Debug/Debugf... funcs so that each of them call inner LoggerInterface.Trace/Tracef/Debug/Debugf/... with your "[sessionid]" + original string. So that your code would look like the Seelog as receiver example snippet, but with |
Note: in the last method above, I meant that you would still need to create your So, you create: type SomeLogger struct {
inner seelog.LoggerInterface
session string
} Then you create all the LoggerInterface funcs (so that your struct can be used exactly like seelog loggers). And you just pass the calls to inner logger with minor changes you need: func (sw *SomeLogger) Debug(s string) {
sw.inner.Debug(sw.session + ":" + s)
}
func (sw *SomeLogger) Trace(s string) {
sw.inner.Info(sw.session + ":" + s)
}
... And now you can create one logger for the whole app:
and then you can just use it per request without any kind of recreation/replacements/etc.:
|
Hi @goodsign Thanks for your very detail information and example. It works perfectly. I have a question regard of SomeLogger. For per-request based logger, we create SomeLogger to fit my usage. To keep the logger, i need to pass logger instance to the invoked function (for keeping the request-id as same). If any possible we can setup a request based logger, just like seelog a package based logger that all function can use seelog as its logger? Another question, may I know if we could build this kind of requirement in custom formatter?
Thank you! |
Hi @chy168! Not sure that I understood the first question. Can you give an example? Regarding the second question, it is not possible at the moment, so the best option for you would be the recipe above, it shouldn't have any drawbacks. |
Hi @goodsign ! Thanks for you reply, i think the first question is solved by myself via my http server arch. One more question about i implement the request-id based logger.
"print.func·015" is not the correct call depth. How can I fix this? Thank you! |
Check out this section. Pay attention to the |
Hi @goodsign simply my code,
|
Can you attach code of full example, where you load logger, set additional stack depth and do the (Please leave only the minimal part) |
Hi @goodsign I create two example in my scenario. If you run the sample, we can get:
After this case, i was trying to investigate and simply this case, narrow down to the simplest code. Here is a example not use 3rd-party library that I tried to reproduce this case. the gist
the logger output is:
Thanks! |
Well, I'm not sure that it doesn't work as designed. You log from an anonymous func, which it correctly reports. Just plain seelog.Debug without any custom loggers and additional stack level would report the same in this case. It reports the func that it is called from (checks using call stack) and in your case it is called from an anonymous func that is returned by If you try this instead: package main
import (
"fmt"
"io"
"net/http"
log "github.com/cihub/seelog"
)
var appLogger log.LoggerInterface
func main() {
logger, log_err := log.LoggerFromConfigAsString(
`
<seelog minlevel="trace" maxlevel="error">
<outputs formatid="main">
<console />
</outputs>
<formats>
<format id="main" format="%Date(2006/01/02 15:04:05.000) [%Level] %Func %Msg%n"/>
</formats>
</seelog>
`)
if log_err != nil {
fmt.Printf("Logger error: %v", log_err)
panic("Cannot initialize logger from config")
}
appLogger = logger
appLogger.SetAdditionalStackDepth(1)
log.ReplaceLogger(appLogger)
defer log.Flush()
http.HandleFunc("/", hello)
http.ListenAndServe(":8000", nil)
}
func hello(w http.ResponseWriter, r *http.Request) {
request_id := "THIS_IS_UUID"
myLogger := &ApiLogger{appLogger, request_id}
myLogger.Debug("I am runnnnning!")
io.WriteString(w, "Hello world!")
}
// Customize logger with request-id
type ApiLogger struct {
inner log.LoggerInterface
RequestId string
}
func (sw *ApiLogger) Debug(s string) {
sw.inner.Debugf(sw.RequestId + " " + s)
}
func (sw *ApiLogger) Info(s string) {
sw.inner.Info(sw.RequestId + " " + s)
}
func (sw *ApiLogger) Error(s string) {
sw.inner.Error(sw.RequestId + " " + s)
}
func (sw *ApiLogger) Debugf(format string, params ...interface{}) {
sw.inner.Debugf(sw.RequestId+" "+format, params...)
} It prints
So I guess that your current problem is not connected to the original topic of our discussion. The problem is that seelog correctly reports the function it is called from, which is an anonymous func that you create, but you probably want something else. |
If you are 100% sure that you are going to log from some "Middleware" func and you won't need log statements outside of them (or you use different logger for that), then you may do this: func hello(w http.ResponseWriter, r *http.Request) {
request_id := "THIS_IS_UUID"
myLogger := &ApiLogger{appLogger, request_id}
myLogger.Debug("I am runnnnning!")
io.WriteString(w, "Hello world!")
} then you'll see this:
(because now it skips 2 frames: ApiLogger.Debug and hello, so it ends up in net/http.HandlerFunc) So, basically, you have to tell seelog (or any other log library), exactly how many stack frames it must skip to find the func name that it reports. No magic here :) |
Hi @goodsign ! |
Hi,
I'm integrating seelog with my http service. I would like to debug with a 'request id' per request/session.
My concept is, once http server receive a request, it will generate a UUID as the request id for this session.
All debug log will include this UUID for identifying till the end of request.
I've read a solution at Custom receivers - Scenario 3.2: Custom receivers with context, but I still had a concern there, please advice.
The concern is, when we instance the 'logger-per-request' log in HttpHandler per request (means it might be parallel),
should I take care of the performance and any potential issue()? I list cases for example:
Thank you, seelog rock! :)
The text was updated successfully, but these errors were encountered: