Go logger with Kubernetes Stackdriver format compatibility
Tags: go, logger, kubernetes, showdev
Published: 2017-11-08 10:42:35

---
title: Go logger with Kubernetes Stackdriver format compatibility
published: true
description: Go logger with Kubernetes Stackdriver format compatibility
tags: go,logger,kubernetes,showdev
---

![](https://thepracticaldev.s3.amazonaws.com/i/hdvkunaczff81azmpw9m.jpg)

_Originally published on [my blog](http://www.nikola-breznjak.com/blog/go/go-logger-kubernetes-stackdriver-format-compatibility/)_

I'm so proud to announce that a Go [Logger](https://github.com/teltech/logger) package that our backend team at [TelTech](http://teltech.co/) was working on is now open-source! It is our library for structured logging mechanism for Go projects running via Kubernetes with [Stackdriver format](https://cloud.google.com/error-reporting/docs/formatting-error-messages) compatibility.

> For those who'd like to get started with Kubernetes, here are two free courses:
> 
> + [Scalable Microservices with Kubernetes by Google](https://www.udacity.com/course/scalable-microservices-with-kubernetes--ud615) on Udacity. [Kelsey Hightower](https://twitter.com/kelseyhightower) is one of the instructors here!
> + [Introduction to Kubernetes](https://www.edx.org/course/introduction-kubernetes-linuxfoundationx-lfs158x) by edX
> 
> For the curious, here's an [overview of logging in Kubernetes](https://kubernetes.io/docs/concepts/cluster-administration/logging).

## Installation

`go get -u github.com/teltech/logger`

## Usage

```
package main

import (
    "github.com/teltech/logger"
)

// There should be a LOG_LEVEL environment variable set, which is read by the library
// If no value is set, the default LOG_LEVEL will be INFO

func main() {
    // Stackdriver requires a project name and version to be set. Use your environment for these values.
    // SERVICE should be your GCP project-id, e.g. robokiller-146813
    // VERSION is an arbitrary value
    log := logger.New()

    // You can also initialize the logger with a context; the values will persist throughout the scope of the logger instance
    log = logger.New().With(logger.Fields{
        "user":   "+1234567890",
        "action": "create-account",
    })

    param := "something useful here"

    // A metric is an INFO log entry without a payload
    log.Metric("CUSTOM_METRIC_ENTRY")

    // Log a DEBUG message, only visible in when LOG_LEVEL is set to DEBUG
    log.With(logger.Fields{"key": "val", "something": true}).Debug("debug message goes here")
    log.With(logger.Fields{"key": "val"}).Debugf("debug message with %s", param)

    // Log an INFO message
    log.With(logger.Fields{"key": "val", "names": []string{"Mauricio", "Manuel"}}).Info("info message goes here")
    log.With(logger.Fields{"key": "val"}).Infof("info message with %s", param)

    // Log a WARN message
    log.With(logger.Fields{"key": "val"}).Warn("warn message goes here")
    log.With(logger.Fields{"key": "val"}).Warnf("warn message with %s", param)

    // Error() prints the stacktrace as part of the payload for each entry and sends the
    // data to Stackdriver Error Reporting service
    log.With(logger.Fields{"key": "val"}).Error("error message goes here")
    log.With(logger.Fields{"key": "val"}).Errorf("error message with %s", param)
}
```

## Output

The errors require a specific JSON format for them to be ingested and processed by Google Cloud Platform Stackdriver Logging and Error Reporting. See [this post](https://cloud.google.com/error-reporting/docs/formatting-error-messages) for more info. The resulting output has the following format, optional fields are, well, optional:


```
 {
  "severity": "ERROR",
  "eventTime": "2017-04-26T02:29:33-04:00",
  "message": "An error just happened!",
  "serviceContext": {
     "service": "robokiller-ivr",
     "version": "1.0"
  },
  "context": {
    "data": {
      "clientIP": "127.0.0.1"
      "userAgent": "Mosaic 1.0"
    },
    "reportLocation": {
      "filePath": "\/Users\/mc\/Documents\/src\/github.com\/macuenca\/apex\/mauricio.go",
      "functionName": "unknown",
      "lineNumber": 15
    }
  },
 "stacktrace": "goroutine 1 [running]:main.main()\n\t\/github.com\/macuenca\/mauricio.go:15 +0x1a9\n"
}
```

Your Google Console StackDriver Error Reporting may then look something like this:

![](https://i.imgur.com/fC8Gk0w.png)

## License
This package is licensed under the [BSD 3-clause](https://opensource.org/licenses/BSD-3-Clause) license.

## Opportunities
If you like this project and would like to work on something similar, go check out [our Careers page](http://teltech.co/careers) - we're always looking for talented new people ðŸ™Œ

## Conclusion
This package has been very helpful to us, so we hope it helps someone else as well. If you have any remarks on the project, please submit a bug or PR ðŸ’ª