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