2

I am trying send info/error logs to StackDriver Logging on GCP from Cloud Function written in Go, however all logs dosen't have log level assignment.

I have created function from https://github.com/GoogleCloudPlatform/golang-samples/blob/master/functions/helloworld/hello_logging.go to demonstrate problem.

link to image with logs

PowerStat
  • 3,757
  • 8
  • 32
  • 57
nephe
  • 21
  • 4

5 Answers5

2

Cloud Support here! What you are trying to do is not possible, as specified in the documentation:

  • Logs to stdout or stderr do not have an associated log level.

  • Internal system messages have the DEBUG log level.

What you probably need is to use Logging API, specifically the Log Levels section.

If this is not working for you either you could try using node.js instead of go as it currently emits logs to INFO and ERROR levels using console.log() and console.error() respectively.

Community
  • 1
  • 1
Miguel
  • 956
  • 6
  • 20
  • I have tried using that library but I cannot get it working. It doesn't returned any errors but nothing is logged to stackdriver. – nephe Aug 07 '19 at 13:26
  • Hello @nephe I have modified my answer with another possible solution for you. i would also like you to run this command: `gcloud functions logs read FUNCTION_NAME`, and verify if you can see the logs in there. – Miguel Aug 07 '19 at 15:13
  • I have tried and it also returns logs without any level, only the ones produced by standard logger, not the one that you have lined. Can you link me to issue where I can monitor when this kind of support will be added to GCF in Go? – nephe Aug 08 '19 at 05:47
  • I have found [this](https://issuetracker.google.com/124403972) public issue requesting the implementation of logging severity for GCF in general. In addition, I've created [this](https://issuetracker.google.com/139174817) issue requesting logging severity for GCF in Go specifically. – Miguel Aug 09 '19 at 09:49
2

I created a package to do exactly this: github.com/ncruces/go-gcp/glog

It works on App Engine, Kubernetes Engine, Cloud Run, and Cloud Functions. Supports setting logging levels, request/tracing metadata, and structured logging.

Usage:

func HelloWorld(w http.ResponseWriter, r *http.Request) {
    glog.Infoln("Hello logs")
    glog.Errorln("Hello logs")
    // or, to set request metadata:
    logger := glog.ForRequest(r)
    logger.Infoln("Hello logs")
}
Nuno Cruces
  • 1,584
  • 15
  • 18
  • 2
    Thanks, it looks that it is working properly and it is setting valid error levels. – nephe Dec 09 '19 at 09:43
  • Hi, I would like to know what permissions should I give my functions so they can use the API. I'm currently receiving an permission error while trying to use in my code – nicolasassi Jul 05 '20 at 19:40
  • Hi can you please answer this? https://stackoverflow.com/questions/72504886/why-google-logging-client-libraries-not-logging-inside-google-cloud-functions – Mohamed Arshad Jun 06 '22 at 07:10
  • No, sorry. My package deliberately avoids using the logging client, instead logging to stdout/err. – Nuno Cruces Jun 06 '22 at 21:54
1

you can use external library which allow you to set the log level. Here an example of what I use. Use logrus for setting the minimal log level (you can improve this code by providing log level in env var) and joonix for fluentd formatter.(line 25)

A point of attention. Line 11, I rename the logrus package log log "github.com/sirupsen/logrus" Thus, don't use log standard library, but logrus library. It's sometime boring... you can simply replace log by logrus for avoiding all confusion.

Joonix is a fluentD formatter for transforming the logs into an ingestable format for Stackdriver.

guillaume blaquiere
  • 66,369
  • 2
  • 47
  • 76
  • I have tried with formatter that you have provided but it still behaves in invalid way. Everything is added as text payload `textPayload: "{"httpRequest":{"requestMethod":"POST","status":200,"responseSize":"31337","userAgent":"Go-http-client/1.1","latency":{"nanos":123000000}},"message":"additional info","severity":"INFO","timestamp":{"seconds":1565175967,"nanos":261743604}}" ` – nephe Aug 07 '19 at 11:07
  • Yes, there is a tricky thing. Look at the line 11 `log "github.com/sirupsen/logrus"` I rename the logrus package to log. Then I use log.debugf(...) for logging in debug level. The formater only transform the output in fluentD format, for an understable ingestion by stackdriver. – guillaume blaquiere Aug 07 '19 at 11:46
  • I am not sure if I understand you. I am using los as `github.com/sirupsen/logrus`. Then I set formatter as `joonix` and set level as `Debug`. However it still results as text payload in stackdriver. – nephe Aug 07 '19 at 12:08
  • You are right. This works on Cloud Run and GCE/GKE but not on Cloud Function. I performed some tests with different logger configuration. I don't understand what is different and why it doesn't work. – guillaume blaquiere Aug 07 '19 at 13:21
1

I, too, took a stab at creating a package for this. If you use logrus (https://github.com/sirupsen/logrus), then this may be helpful:

https://github.com/tekkamanendless/gcfhook

I'm using this in production, and it's working just fine.

Douglas Manley
  • 1,093
  • 13
  • 18
0

I recommend the https://github.com/apsystole/log. It's also log- and logrus-compatible, but a small zero-dependency module unlike the libraries used in two existing answers which bring 400+ modules as their dependencies (gasp... I am simply looking at go mod graph).

kubanczyk
  • 5,184
  • 1
  • 41
  • 52