Exploring Slog package: The new log library of The Go Programming Language
Tags: go, slog, logging
Published: 2023-08-29 13:19:17

---
title: Exploring Slog package: The new log library of The Go Programming Language
published: true
date: 2023-08-28 16:51:15 UTC
tags: #go #slog #logging
canonical_url: https://carlosmv.hashnode.dev/exploring-slog-package-the-new-log-library-of-the-go-programming-language
---

DISCLAIMER: This is not a comprehensive article about the Slog package.

This article covers how to create info, warning and error logs; and how to use the level feature, the `TextHandler` and `JSONHandler`.

### Slog Package

The Slog package is a logging package added to the standard library in the Go 1.21 version.

This package, according to its [documentation](https://pkg.go.dev/golang.org/x/exp/slog), provides structured logging, in which log records include a message, a severity level, and various other attributes expressed as key-value pairs.

It defines a type, Logger, which provides several methods (such as `Logger.Info`, `Logger.Warn`, `Logger.Debug` and `Logger.Error`) for reporting events of interest.

```
package main

import "log/slog"

func main() {
    logger := slog.Default()

    logger.Info("An info log")
    logger.Warn("A warn log")
    logger.Error("An Error log")
}

```

In the code above, we define the `logger` variable and create a `slog` instance with the `Default()` log.

We create a log for Info, Warn and Error.

We run the program and we will this output in the console:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1692974459055/1592e954-de25-483e-a989-985ff11b8786.png)

### Handlers

The logger. `slog` comes with two built-in handlers. A `TextHandler` and a `JSONHandler`. The `TextHandler` emits all log information in the form `key=value` pairs.

```
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
logger.Info("hello, world", "user", "Some user")

```

Now the output looks like this:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1693014261898/beb087ec-a27e-4dd9-9241-7eec1e5bccaa.png)

For JSON output, we can use the built-in `JSONHandler` instead:

```
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
logger.Info("hello, world", "user", "Some user"))

```

Now our output is a sequence of JSON objects:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1693014324487/39c099cd-3993-4f71-964b-acb6433d02ad.png)

### Levels

As de documentation says, a Level is an integer representing the importance or severity of a log event. The higher the level, the more severe the event. This package defines constants for the most common levels, but any int can be used as a level.

In an application, you may wish to log messages only at a certain level or greater.

```
package main

import (
    "log/slog"
    "os"
)

const (
    LevelDebug = slog.Level(-4)
    LevelInfo = slog.Level(0)
    LevelWarn = slog.Level(4)
    LevelError = slog.Level(8)
)

func main() {
    handler := slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{Level: LevelError})
    jsonLogger := slog.New(handler)
    jsonLogger.Info("An info log")
    jsonLogger.Warn("A warn log")
    jsonLogger.Error("An Error log")

}

```

In the code snippet above, we declare the levels and create a JSON handler to show only logs of the level: `LevelError`. So any log below level 8, will not be shown. If we run this program, it will show the following output:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1692980437523/742a1379-2c8e-4368-a932-cb3682eb246a.png)

Now, we are going to create a server that shows in the terminal the port where the server is listening as an INFO log and if there is an error, an Error log.

```
package main

import (
    "log/slog"
    "net/http"
    "os"
)

func main() {
    mux := http.NewServeMux()
    port := ":3000"

    logger := slog.Default()

    mux.Handle("/", http.HandlerFunc(homeHandler))

    logger.Info("Listening on ", "port", port)

    err := http.ListenAndServe(port, mux)
    if err != nil {
        logger.Error("Problem starting the server", "error", err)
    }

}

func homeHandler(w http.ResponseWriter, r *http.Request) {

    w.Write([]byte("Hello World"))

}

```

In this case, I have another server using the port 3000. The terminal shows the following output:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1692973934124/24e537c6-a76c-4c53-a866-ed5f86722783.png)

### Conclusion

The Go programming Language didn't have in its log package features like the slog package provides. To print in the console logging information about our programs we use functions like `log.Println()`, `log.Fatal()`, etc. We have to use third-party logging libraries to use features like levels, JSON handlers, or classifying the logs by Info, Warn, Debug and Error.

With this package, we can create appropriate logs for our programs without relying on third-party libraries.

Thank you for taking the time to read this article.

If you have any recommendations about other packages, architectures, how to improve my code, my English, or anything; please leave a comment or contact me through [**Twitter**](https://twitter.com/Carlos_marcv), or [**LinkedIn**](https://www.linkedin.com/in/carlos-marcano-a2135a134/).

### Resources

[Slog Package Documentation](https://pkg.go.dev/golang.org/x/exp/slog)

[Structured Logging with slog](https://go.dev/blog/slog)

[A Comprehensive Guide to Logging in Go with Slog](https://betterstack.com/community/guides/logging/logging-in-go/)