sloggcp provides utilities to integrate Go's slog logging with Google Cloud Platform (GCP) structured logging.
It provides a simple implementation of the ReplaceAttr
function for JSONHandler from slog.
This implementation adapts the default slog attributes to be compatible with Google Cloud Platform's Structured Logging, by replacing the following attribute keys:
| Slog key | GCP key |
|---|---|
level |
severity |
msg |
message |
source |
logging.googleapis.com/sourceLocation |
time |
time |
sloggcp comes with a error reporting handler, which turns a log line
into a formatted error message whenever an error is part of the attributes.
This enables GCP Error Reporting through logging.
See the documentation for more details.
go get github.com/zitadel/sloggcp@latestpackage main
import (
"github.com/zitadel/sloggcp"
"log/slog"
"os"
)
func main() {
logger := slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{
ReplaceAttr: sloggcp.ReplaceAttr,
AddSource: true,
Level: slog.LevelDebug,
}))
slog.SetDefault(logger)
}package main
import (
"errors"
"fmt"
"log/slog"
"os"
_ "runtime/debug"
"time"
"github.com/zitadel/sloggcp"
)
type AppError struct {
Parent error
Message string
reportLocation *sloggcp.ReportLocation
stackTrace []byte
}
// Error implements [error].
func (e AppError) Error() string {
return fmt.Sprintf("%s: %v", e.Message, e.Parent)
}
// ReportLocation implements [sloggcp.ReportLocationError].
func (e AppError) ReportLocation() *sloggcp.ReportLocation {
return e.reportLocation
}
// StackTrace implements [sloggcp.StackTraceError].
func (e AppError) StackTrace() []byte {
return e.stackTrace
}
// LogValue implements [slog.LogValuer].
func (e AppError) LogValue() slog.Value {
var parent slog.Attr
if v, ok := e.Parent.(slog.LogValuer); ok {
parent = slog.Any("parent", v)
} else {
parent = slog.String("parent", e.Parent.Error())
}
return slog.GroupValue(
slog.String("message", e.Message),
parent,
)
}
func main() {
h := sloggcp.NewErrorReportingHandler(os.Stdout, &slog.HandlerOptions{
Level: slog.LevelInfo,
// Replace "err" key with the standard [ErrorKey] for GCP error reporting.
ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
if len(groups) != 0 {
return a
}
if a.Key == "err" {
a.Key = sloggcp.ErrorKey
}
return a
},
})
logger := slog.New(h).With(sloggcp.TimeKey, time.Time{}) // for deterministic output
// Simple string error
logger.Error("", "err", errors.New("something went wrong"))
err := AppError{
Parent: errors.New("database connection failed"),
Message: "failed to fetch user data",
reportLocation: &sloggcp.ReportLocation{
FilePath: "user_service.go",
LineNumber: 42,
FunctionName: "fetchUserData",
},
stackTrace: []byte("[STACK TRACE]"), // normally call [debug.Stack]
}
logger.Error("", "err", err)
// Output:
// {"@type":"type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent","error":"something went wrong","message":"something went wrong","severity":"ERROR","time":"0001-01-01T00:00:00Z"}
// {"@type":"type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent","error":{"message":"failed to fetch user data","parent":"database connection failed"},"message":"[STACK TRACE]","reportLocation":{"filePath":"user_service.go","lineNumber":42,"functionName":"fetchUserData"},"severity":"ERROR","time":"0001-01-01T00:00:00Z"}
}For security reasons, we normally only support and recommend the use of one of the latest two Go versions (:white_check_mark:). Versions that also build are marked with :warning:.
sloggcp depends on functions only implemented in Go 1.25 and later.
| Version | Supported |
|---|---|
| <1.25 | ❌ |
| 1.25 | ✅ |
The full functionality of this library is and stays open source and free to use for everyone. Visit our website and get in touch.
See the exact licensing terms here
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.