How to generate a log every day

Comment From: manucorporat

@YeFatBoy please, can you elaborate?

Comment From: JimmyPettersson85

I'm assuming he wants something like logrotate in Gin.

This creates/opens a file named YYYY-MM-DD.log that you can write to (no error handling). You'd have to do this for each request in a middleware.

now := time.Now() //or time.Now().UTC()
logFileName := now.Format("2006-01-02") + ".log"
logFile, _ := os.OpenFile(path.Join("/path/to/store/logs", logFileName), os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
defer logFile.Close()
fileLogger := log.New(logFile, "", 0)
fileLogger.Printf(...)

It's probably better to use a processmanager like supervisord that has logrotate built in though.

Comment From: nazwa

Why don't you set the file as a default log output?

You can then use a timer to tick every 24 hours and change output file.


// Cant't write properly right now, so this is just a stub to give you the idea

func rotateLogs() {


for  {


select {
case <-time.Tick(24 * time.Hours):

// create a new log with file name xxx or more the existing one
f, err := os.OpenFile("testlogfile", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
if err != nil {
    t.Fatalf("error opening file: %v", err)
}

// set default log output to the 'new' file
log.SetOutput(f)
log.Println("This is a test log entry")
defer f.Close()
}

Comment From: JimmyPettersson85

@nazwa There's a few problems with that approach. - You wont have daily logs unless you start you program at exactly 00.00 - It wont handle DST - It's missing logic to create unique file names

Comment From: YeFatBoy

@manucorporat I want to get all http requests everyday,how to generate a log for every date?

Comment From: nazwa

Of course but like I said, this was just to give you an idea, which I wrote on the go.

Instead of a ticker you would use a timer that triggers at 00:01 and changes the output file. And of course on startup you set it to current date. I think the concept is exactly the same.

It gets tricky later in how do you actually write down the requests, but if you look at the default gin logger middleware and add some sort of buffering to it, so logs are written in batches (for performance reasons) it should be quite good and simple.

Comment From: manucorporat

@YeFatBoy @slimmy @nazwa I would say that you should not try to implement this in the application: - Unneeded complexity - Difficult to debug ( it is very nicer to see the logs right in the console when debugging) - Different abstraction layers (log rotation is not business logic) - Difficult to scale (what is you generate 10GB of logs per day?)

When deploying in production just use supervisord or similar: this is how I start my server:

supervisord start server

this is how a see the logs in real-time

supervisorctl tail -f server

Also supervisor does log rotation automatically and manages backups. http://supervisord.org/logging.html

Of course you can try to implement it, but in my opinion it will be a less elegant solution. Just create your LogRotator struct{} that implements io.Writer and pass it to LoggerWithWriter()

Comment From: beef9999

Log rotate is a key feature in any mature server side program. I'm really suspicious gin had ever considered to developed to a fully functional http server. Think about Tornado, Django in Python, and those famous Java web containers. They are called framework because they did more than a simple tool should do. @manucorporat

Comment From: goupeng212

Totally agreed with @beef9999 , gin-gonic should add log rotate features, otherwise the framework is not a mutual one.

Comment From: robvdl

Just my 2c:

I think a web framework shouldn't do log rotation, or even write out log files, it should log to stdout and be captured by the process manager (supervisord, systemd, whatever, aka 12 factor app style), the process manager writes it to disk not the web app.

Log rotation should be handled automatically then by the process manager and logrotate daemon.

Doing it yourself adds unecessary complexity to a web framework

https://12factor.net/logs

Comment From: gplume

Agreed on that @robvdl. But I don't recommend supervisord for this particular log task as I've experimented struggles under heavy loads (gin is rather verbose...).

Comment From: beef9999

@gplume

That's because there is no way for a 3rd-party process or even the system to force the target process to do log-rotate. Only if the target is willing to, usually by responding to signals.

What these tools do, such as supervisord or logrotated, are simply copy the original log file and paste it to another file, which might cause sequence issues if the logs are plenty.

In a word built-in logrotate is an essential feature...

Comment From: tboerger

Gin itself should not get any log rotation, but it should accept a custom logger to give the option to implement something like that on an application

Comment From: nowissan

I suppose logrotated with copytruncate setting will do. Am I wrong?

Comment From: burkayaltuntas

this is my solution for it.

https://medium.com/@burkayaltuntas/daily-log-rotation-for-golang-gin-6eb6ec278479