Write Logs to memory

Hi,
Can anyone suggest me how to write logrus logs into the memory in golang?

Thanks in advance.

The Out field in the logrus Logger struct is an io.Writer interface type which means you can assign anything to it that implements the Write method:

type Writer interface {
        Write(p []byte) (n int, err error)
}

If you want to write to memory you can use the standard library’s bytes.Buffer as it has a Write([]byte) (int,error) method.
Assign an instance of bytes.Buffer to the Out field and all your logs will be streamed to the buffer:

var memLog bytes.Buffer
log.SetOutput(memLog)

Just a word of warning that you would need to clear/reset/flush your buffer now and then otherwise you will run out of memory at some point.

[EDIT] I’m curious why you would want to keep logs in memory? What’s the use case?

1 Like

Thanks,

Can you also tell me how can I read logs from it in future?I have to keep in memory as our code on heroku and heroku support only readlonly filesystem.So we can not write logs to file.So I am trying to save logs into memory then move this into mysql at some time interval.

If future means while the program is still running, memLog.Read along with the other methods from bytes.Buffer will work.

If future means after the program has completed or it has been restarted, then you can’t because the logs only existed in memory. You need to write them to a file or something else persistent.

In future means when program is running.

Using bytes.Buffer is the easiest and most straightforward way, but if you need something more sophisticated, and if you don’t mind using a third-party library, then have a look at Afero. This is a file system abstraction library that includes a memory-mapped filesystem backend. But be careful to not over-engineer the solution to your problem. If bytes.Buffer already meets your needs, stay with that.

1 Like

Hi when I am using this,it throws following error:-

./main.go:318: cannot use memLog (type bytes.Buffer) as type io.Writer in argument to logrus.SetOutput:
bytes.Buffer does not implement io.Writer (Write method has pointer receiver)

However,when I replaced bytes.buffer with io.writer then it throws following error:

nirmalchauhan@CG6QFY1:~/heroku-logrus-test/src/fast-wave-40866$ go run main.go
INFO[0000] Broadscaler app initializing…
here is log%!(EXTRA string={“LineNo”:1998})panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x20 pc=0x468f02]

goroutine 1 [running]:
panic(0xb28ea0, 0xc82000a140)
/usr/local/go/src/runtime/panic.go:464 +0x3e6
fast-wave-40866/vendor/github.com/Sirupsen/logrus.Entry.log(0xc8200121e0, 0xc8202ac090, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, …)
/home/nirmalchauhan/heroku-logrus-test/src/fast-wave-40866/vendor/github.com/Sirupsen/logrus/entry.go:113 +0x622
fast-wave-40866/vendor/github.com/Sirupsen/logrus.(*Entry).Info(0xc8202b2000, 0xc82011fec0, 0x1, 0x1)
/home/nirmalchauhan/heroku-logrus-test/src/fast-wave-40866/vendor/github.com/Sirupsen/logrus/entry.go:140 +0x91
fast-wave-40866/vendor/github.com/Sirupsen/logrus.(*Logger).Info(0xc8200121e0, 0xc82011fec0, 0x1, 0x1)
/home/nirmalchauhan/heroku-logrus-test/src/fast-wave-40866/vendor/github.com/Sirupsen/logrus/logger.go:188 +0x5b
fast-wave-40866/vendor/github.com/Sirupsen/logrus.Info(0xc82011fec0, 0x1, 0x1)
/home/nirmalchauhan/heroku-logrus-test/src/fast-wave-40866/vendor/github.com/Sirupsen/logrus/exported.go:87 +0x41
main.main()
/home/nirmalchauhan/heroku-logrus-test/src/fast-wave-40866/main.go:412 +0x388
exit status 2

Please suggest what to do?

Try passing the memLog by reference rather than value:

    var memLog bytes.Buffer
    log.SetOutput(&memLog)
1 Like

Thank you so much.It really worked!

1 Like

Try passing the memLog by reference rather than value

This is a little pedantic, but Go only passes by value. In this case the value is a pointer to memLog.

Other uses of memLog will probably also require a pointer receiver. As such, I usually initialize with:

memLog := &bytes.Buffer{}

to give me a non-nil pointer to a bytes.Buffer

1 Like

var memLog bytes.Buffer

log.SetOutput(&memLog)

After that when I am printing the memLog its giving me following data which means no data is writing to the memory:-

fmt.Println(memLog)

{[] 0 [0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 0}

Not sure what you are doing between setting the output and attempting to print memLog. It’s really hard to figure out what is going wrong in code we can’t see. So here is a working example (based on the example in the docs):

package main

import (
	"bytes"
	"fmt"

	log "github.com/sirupsen/logrus"
)

func main() {
	memLog := &bytes.Buffer{}
	log.SetOutput(memLog)

	log.WithFields(log.Fields{
		"animal": "walrus",
		"number": 1,
		"size":   10,
	}).Info("A walrus appears")

	fmt.Println(memLog)
}

which, when ran, outputs:

INFO[0000] A walrus appears                              animal=walrus number=1 size=10

I appreciate that you are modifying some more extensive code, but I find that when I am trying to figure something out and having problems with it a little program really helps out, not just for me but also for the people trying to help me.

2 Likes

Following is my code for writing logs to memory.When I am printing the memlog in Init() function. it always gives {[] 0 [0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 0}.Please suggest what wrong I am doing.

https://play.golang.org/p/afW2YgF84d

Please check this link for my code

Pretty please format your code with the [code] macro

The code you have provided does not compile, you cannot call init() from main().

Can you share your code on the playground or a gist?

https://play.golang.org/p/afW2YgF84d

The code you provided calls init, which sets up the memory writer for your logger, then it prints the contents of the buffer then it exits.

I’m pretty sure that program won’t compile, and even if it did, it is doing no work.

I was able to write logs into the file but not able to write into memory from this code

This code doesn’t compile, and if it did, main calls init then exits. That is why you have no log data.

I have modified the code.Please check it on following link.

https://play.golang.org/p/MRpK6yehql