liveBook · Manning

Monitoring

As explained in Go in Practice, Second Edition

Logging is the recording of program events and diagnostic information for later inspection.

Monitoring helps you find production problems, recognize when load calls for scaling, and understand what an application is doing. Start by logging errors and other useful events. Logs can be written to disk for another application to read or sent to a monitoring service. section 12.5

For ordinary events, Go’s standard log package is a practical replacement for console print calls: its output adds diagnostic context, and SetFlags controls details such as time and filename. When plaintext messages become difficult to search or parse, log/slog adds levels and structured output, including JSON. Configure its level to include debug messages when you need them. section 6.2 section 6.2.2

Application events are only part of the picture. Go’s runtime also exposes processor count, goroutine count, memory use, and garbage-collection details. Read selected values at regular intervals and write them to a log or monitoring service. A rising goroutine count, for example, can expose a library update that leaves goroutines running instead of letting them disappear. section 12.5

Listing 12.13 Monitoring an application’s runtime
func monitorRuntime() {  #1
     log.Println("Number of CPUs:", runtime.NumCPU())  #2
     m := &runtime.MemStats{}
     for {  #3
            r := runtime.NumGoroutine()  #4
            log.Println("Number of goroutines", r)  #4
            runtime.ReadMemStats(m)  #4
            log.Println("Allocated memory", m.Alloc)  #4
            time.Sleep(10 * time.Second)  #5
     }
}
func main() {
     go monitorRuntime()  #6
     i := 0                                          #7
     for i < 40 {  #7
            go func() {  #7
                   time.Sleep(15 * time.Second)  #7
            }()  #7
            i = i + 1  #7
            time.Sleep(1 * time.Second)  #7
     }                                               #7
} #7

This Go example starts monitoring in a goroutine alongside the application. It records CPU count, then logs goroutine count and allocated memory every ten seconds while a workload creates goroutines. section 12.5

Listing 6.8 Log levels
package main

import (
    "log/slog"
)

func main() {
    slog.Info("this is default logging")
    slog.Warn("keep an eye on this, it might be an issue")
    slog.Error("oh no, an error happened here!")
    slog.Debug("this is good while developing ...")
}

Compare Info, Warn, Error, and Debug calls. The accompanying default output omits Debug, illustrating why log-level configuration matters when choosing what to record. section 6.2.2

How Go in Practice, Second Edition covers it

How deep it goes
Shows periodic runtime polling in a goroutine and compares basic with structured logging; does not detail a monitoring-service deployment.
Examples
Uses log-level calls and a Go workload that creates goroutines while recording goroutine count and allocated memory.
What it assumes
Assumes basic Go application code and introduces standard logging and runtime polling through concrete examples.
What you can do after
Build it from scratch using Go’s runtime measurements and logging packages to record application events and resource use.
How it connects
Connects logging and structured logging with goroutines, memory allocation, garbage collection, and horizontal scaling.

Also explained in

Compare how 40 books explain monitoring →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Go in Practice, Second Edition. The section links point to the parts of the book it draws on.