Official agent skill

fp-go Logging Patterns

by IBM in IBM/fp-go

Adds logging to fp-go functional pipelines with Tap operators, entry and exit logs and error context, so that logging never changes the value or error flowing through.

OfficialApache-2.0Auto-check passedDevelopment

Install fp-go Logging Patterns

skills CLI
$ npx skills add IBM/fp-go --skill fp-go-logging -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install IBM/fp-go fp-go-logging --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/IBM/fp-go.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/fp-go-logging .claude/skills/fp-go-logging && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
fp-go-logging
GitHub stars
2k
Token cost
~3.7k tokens
SKILL.md length
1,095 words
Files
1
Skills in repo
10
Repo updated
First seen
Licence
Apache-2.0

At a glance

Adds logging to fp-go functional pipelines with Tap operators, entry and exit logs and error context, so that logging never changes the value or error flowing through.

  • Works in 3 steps: A Simple Log Statement with Tap → Entry and Exit Logs → Adding Context to the Error Channel
  • Adding structured slog logging inside an fp-go Pipe or Flow
  • SKILL.md covers Before You Generate, Quick Reference, 1. A Simple Log Statement with… and 2. Entry and Exit Logs, plus 4 more sections
  • Calls go

What it does

Logging is treated as a side effect: a `Tap` runs an effect on the current value or error and passes the original computation on unchanged. The skill covers three tasks: a simple log statement with `TapSLog`, `TapIOK`, `TapReaderIOK` or `TapLeft`, entry and exit logs with `LogEntryExit`, and adding context to the error channel with `MapLeft` and `errors.OnError` and then logging once. A quick reference table maps goals to operators on a `ReaderIOResult`, including debug-level variants, success-only and error-only logging, printf-style output, custom attributes, timing with a correlation ID, and choosing the logger for a pipeline with `logging.WithLogger`.

Because fp-go signatures are easy to misremember, the agent looks up unfamiliar combinators through the fp-go MCP server's `search_examples` and `get_example` tools, and after writing code runs `go build` and `go vet` across the module to catch type-parameter and argument-order errors. Runnable examples live in a logging example test file in the library's `readerioresult` package.

When your agent uses it

  • Adding structured slog logging inside an fp-go Pipe or Flow
  • Logging entry and exit of a ReaderIOResult step with timing
  • Attaching context to an error before it is logged once
  • Putting a request-scoped logger into the context for a pipeline

Example prompts

  • “Add TapSLog to the loadUser pipeline so each result is logged without changing it.”
  • “Wrap fetchOrders with LogEntryExit at debug level.”
  • “Add the user ID to the error with MapLeft and log it a single time.”

Requirements

  • Go with the fp-go v2 library
  • The fp-go MCP server, for looking up combinators

Workflow steps

3 steps, taken from the step headings in SKILL.md.

  1. A Simple Log Statement with Tap
  2. Entry and Exit Logs
  3. Adding Context to the Error Channel

What it can do on your machine

Read from SKILL.md and the folder at commit 1c4245d. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • go

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

fp-go Logging Patterns loads about 3.7k tokens when it runs. Until then it costs about 130 tokens; SKILL.md has 1,095 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~130
When it runs · the whole SKILL.md, loaded when a task matches
~3.7k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from IBM/fp-go at commit 1c4245d, republished under its Apache-2.0 licence (© IBM). 1,095 words, ~3,723 tokens.

Download SKILL.mdSave it as .claude/skills/fp-go-logging/SKILL.md (or your agent's skills folder).
name
fp-go-logging
description
Use this skill when adding logging to fp-go functional pipelines (github.com/IBM/fp-go/v2). Trigger on logging inside Pipe/Flow, Tap/TapIOK/TapReaderIOK/TapLeft used for logging, TapSLog, SLogLeft/SLogRight, entry/exit logging (LogEntryExit, LogEntryExitWithCallback), correlation IDs, adding context to errors before they are logged (MapLeft with errors.OnError), request-scoped slog loggers in context.Context (logging.WithLogger, GetLoggerFromContext), or IO.Logf/Printf in IO/IOResult/ReaderIOResult.

fp-go Logging

Logging is a side effect: it must never change the value or the error flowing through a pipeline. fp-go expresses this with the Tap* family of operators. A Tap runs an effect on the current value (or error) and hands the original computation downstream unchanged.

This skill covers three tasks:

  1. Add a simple log statement: TapSLog, TapIOK, TapReaderIOK, TapLeft
  2. Add entry and exit logs: LogEntryExit
  3. Add context to the error channel: MapLeft + errors.OnError, then log once

Examples assume these imports; all live under github.com/IBM/fp-go/v2:

go
import (
    "log/slog"

    RIO "github.com/IBM/fp-go/v2/context/readerioresult"
    ER  "github.com/IBM/fp-go/v2/errors"
    F   "github.com/IBM/fp-go/v2/function"
    IO  "github.com/IBM/fp-go/v2/io"
    "github.com/IBM/fp-go/v2/logging"
    R   "github.com/IBM/fp-go/v2/result"
)

Runnable versions of the snippets are in v2/context/readerioresult/logging_example_test.go (ExampleTapSLog, ExampleTapIOK_logging, ExampleTapReaderIOK_logging, ExampleSLogRight, ExampleSLogLeft, ExampleLogEntryExit, ExampleLogEntryExit_nested, ExampleLogEntryExitWithCallback, ExampleMapLeft, ExampleMapLeft_logging).

Before You Generate

fp-go is low-frequency in training data, so signatures are easy to misremember. For any combinator not shown below, look it up via the fp-go MCP server's search_examples / get_example tools (see the fp-go-mcp skill) instead of guessing. After writing code, run go build ./... and go vet ./... and fix any type-parameter or argument-order errors before presenting it.

Quick Reference

GoalOperator (in F.Pipe on a ReaderIOResult[A])
Log value or error, structuredRIO.TapSLog[A]("msg")
Same at DEBUG levelRIO.TapSLogDebug[A]("msg")
Log success onlyRIO.Tap(RIO.SLogRight[A]("msg"))
Log error only (ERROR level)RIO.TapLeft[A](RIO.SLogLeft("msg"))
printf-style log of the valueRIO.TapIOK(IO.Logf[A]("msg: %v"))
Custom attributes / custom messageRIO.TapReaderIOK(logX) with logX: func(A) ReaderIO[Void]
Entry + exit logs with timing and correlation IDRIO.LogEntryExit[A]("name")
Entry + exit at another levelRIO.LogEntryExitWithCallback[A](slog.LevelDebug, logging.GetLoggerFromContext, "name")
Add context to an errorRIO.MapLeft[A](ER.OnError("loading user %d", id))
Choose the logger for a pipelineRIO.Local[A](logging.WithLogger(l))

Tap* and ChainFirst* are aliases (TapIOK = ChainFirstIOK, TapLeft = ChainFirstLeft, …). Prefer the Tap names for logging; they state the intent.

1. A Simple Log Statement with Tap

Default: TapSLog

TapSLog[A](msg) is an Operator[A, A]. Put it in the pipe after the step you want to observe. It logs value=<A> on success or error=<err> on failure at INFO level, using the logger from the context, and returns the computation unchanged.

go
func greeting(id int) RIO.ReaderIOResult[string] {
    return F.Pipe2(
        fetchUser(id),
        RIO.TapSLog[User]("fetched user"),
        RIO.Map(getName),
    )
}
// level=INFO msg="fetched user" value="{ID:42 Name:Alice}"
// level=INFO msg="fetched user" error="not found"
  • Logs happen when the pipeline runs, not when it is built.
  • The type parameter is the type at that point in the pipe (User here, not string).
  • TapSLogInfo / TapSLogDebug choose the level explicitly. Debug logs cost nothing when the logger's level filters them out.
  • context/readerresult and context/readerio have their own TapSLog[A] with the same usage.
Printf-Style: TapIOK with IO.Logf

Any io.Kleisli[A, B] (func(A) IO[B]) can be tapped with TapIOK. The io package has ready-made ones:

go
RIO.TapIOK(IO.Logf[User]("fetched user %+v"))       // log.Printf
RIO.TapIOK(IO.LogGo[User]("user {{.Name}}"))        // text/template, log.Println
RIO.TapIOK(IO.Printf[User]("fetched user %+v\n"))   // fmt.Printf (stdout, no timestamp)
RIO.TapIOK(IO.Logger[User](myStdLogger)("user"))    // custom *log.Logger

These use the standard log package, not slog, and log only on success; an error skips the tap. Prefer TapSLog when the application uses structured logging.

The same operator exists for the other monads: IOR.TapIOK (ioresult), RR.TapIOK (context/readerresult), IO.ChainFirst (plain IO).

Custom Attributes: TapReaderIOK

When you want a specific message and specific attributes, write a small named func(A) ReaderIO[Void] that reads the logger from the context. Reading from the context means the log uses the request-scoped logger and inherits the correlation ID of an enclosing LogEntryExit.

go
import RIOC "github.com/IBM/fp-go/v2/context/readerio"

func logUserLoaded(u User) RIOC.ReaderIO[F.Void] {
    return func(ctx context.Context) IO.IO[F.Void] {
        return func() F.Void {
            logging.GetLoggerFromContext(ctx).InfoContext(ctx, "user loaded", "id", u.ID, "name", u.Name)
            return F.VOID
        }
    }
}

pipeline := F.Pipe2(
    fetchUser(42),
    RIO.TapReaderIOK(logUserLoaded),
    RIO.Map(getName),
)
// level=INFO msg="user loaded" id=42 name=Alice

Do not call slog.Info(...) from inside RIO.Map: Map is for pure functions, and the global logger ignores the logger scoped to the context.

Success Only / Error Only

SLogRight and SLogLeft are Kleisli arrows, so they go through Tap / TapLeft:

go
RIO.Tap(RIO.SLogRight[User]("fetched user"))             // INFO, success only
RIO.TapLeft[User](RIO.SLogLeft("fetching user failed"))   // ERROR, error only; the error still propagates

TapLeft needs the explicit [A] because A cannot be inferred from the error handler.

Common Mistakes
go
// ❌ SLog is Kleisli[Result[A], Void]: its input is the Result, not A, so this does not compile
RIO.Chain(RIO.SLog[User]("fetched"))
// ✅
RIO.TapSLog[User]("fetched")

// ❌ Chain replaces the value with Void
RIO.Chain(RIO.SLogRight[User]("fetched"))
// ✅
RIO.Tap(RIO.SLogRight[User]("fetched"))

// ❌ side effect inside a pure Map; bypasses the context logger
RIO.Map(func(u User) User { slog.Info("fetched", "user", u); return u })
// ✅
RIO.TapSLog[User]("fetched")

2. Entry and Exit Logs

LogEntryExit[A](name) is an Operator[A, A] that wraps the computation it is applied to. It logs [entering] before that computation starts and [exiting ] (success) or [throwing] (failure, with the error) after it ends. Both records carry the same correlation ID, and the exit record carries the duration.

go
func loadUser(id int) RIO.ReaderIOResult[User] {
    return F.Pipe1(
        fetchUser(id),
        RIO.LogEntryExit[User]("loadUser"),
    )
}
// level=INFO msg=[entering] ID=7 name=loadUser
// level=INFO msg="[exiting ]" ID=7 name=loadUser duration=1.2ms
//
// on failure:
// level=INFO msg=[entering] ID=8 name=loadUser
// level=INFO msg=[throwing] ID=8 name=loadUser duration=0.4ms error="not found"
What Gets Wrapped

In a F.Pipe, LogEntryExit wraps everything above it. Put it last to time a whole function, or apply it to a single step to time just that step:

go
// Whole pipeline: the TapSLog runs between entry and exit and is logged with the same ID
loadName := F.Pipe3(
    fetchUser(42),
    RIO.TapSLog[User]("fetched user"),
    RIO.Map(getName),
    RIO.LogEntryExit[string]("loadName"),
)
// level=INFO msg=[entering] ID=3 name=loadName
// level=INFO msg="fetched user" ID=3 value="{ID:42 Name:Alice}"
// level=INFO msg="[exiting ]" ID=3 name=loadName duration=…

// One step inside a larger pipeline: wrap the Kleisli, not the pipeline
F.Pipe2(
    fetchUser(42),
    RIO.Chain(F.Flow2(fetchOrders, RIO.LogEntryExit[[]Order]("fetchOrders"))),
    RIO.Map(summarize),
)

Nested LogEntryExit calls each get their own ID. The ID is installed on the context logger for the wrapped computation, so every context-aware log inside it (TapSLog, SLogLeft, TapReaderIOK using GetLoggerFromContext) is correlated automatically.

Show full SKILL.md (451 more words)Show less
Why Not TapSLog("entering")?

A Tap placed before a step runs after the previous step. It can mark "about to start", but it cannot log the end of a failed step, measure the duration or correlate the two records. Use LogEntryExit for entry/exit logging.

Level and Logger
go
RIO.LogEntryExitWithCallback[User](slog.LevelDebug, logging.GetLoggerFromContext, "loadUser")

If the logger does not have the level enabled, the whole instrumentation (ID, timer, both records) is skipped. The second argument is any func(context.Context) *slog.Logger.

3. Adding Context to the Error Channel

An error usually surfaces far from where it happened. Logging it at every layer produces duplicate records that lack context. The idiomatic approach:

  1. Enrich the error where the context is known, with MapLeft and errors.OnError.
  2. Log once, at the boundary (handler, command, job), with TapLeft(SLogLeft(...)), TapSLog, or the [throwing] record of LogEntryExit.
MapLeft + errors.OnError

RIO.MapLeft[A](f Endomorphism[error]) rewrites the error and leaves successes untouched. ER.OnError(format, args...) builds such an endomorphism. It wraps the original error with %w, so errors.Is / errors.As keep working.

go
func loadGreeting(id int) RIO.ReaderIOResult[string] {
    return F.Pipe2(
        fetchUser(id),
        RIO.Map(getName),
        RIO.MapLeft[string](ER.OnError("loading greeting for user %d", id)),
    )
}
// err.Error() == "loading greeting for user 7, Caused By: not found"
// errors.Is(err, ErrNotFound) == true

Capture the inputs that explain the failure (id above) from the enclosing Kleisli's parameters. The error then says which call failed, not just that one failed.

Log Once at the Boundary
go
func handle(id int) RIO.ReaderIOResult[string] {
    return F.Pipe2(
        loadGreeting(id),
        RIO.MapLeft[string](ER.OnError("handling request")),
        RIO.TapLeft[string](RIO.SLogLeft("request failed")),
    )
}
// level=ERROR msg="request failed" error="handling request, Caused By: loading greeting for user 7, Caused By: not found"
Combine with LogEntryExit

[throwing] logs the error as it leaves the wrapped computation. Put MapLeft above LogEntryExit so the exit record includes the context:

go
F.Pipe2(
    fetchUser(id),
    RIO.MapLeft[User](ER.OnError("loading user %d", id)),  // enrich first …
    RIO.LogEntryExit[User]("loadUser"),                      // … then [throwing] logs the enriched error
)
Rules
  • Use MapLeft to change the error. Do not use OrElse/ChainLeft with RIO.Left just to rewrap; those are for recovery.
  • Always wrap with %w (which ER.OnError does). fmt.Errorf("…: %v", err) breaks errors.Is.
  • Enrich where the context is; log where the error is handled. A TapLeft log in every layer duplicates the record.
  • MapLeft is available in context/readerioresult, context/readerresult, context/readerreaderioresult, readerresult, result and ioresult. In result/ioresult the function has type func(error) E; ER.OnError(...) fits with E = error.

Choosing the Logger

All context-aware operators (TapSLog*, SLogLeft/Right, LogEntryExit*) read the logger with logging.GetLoggerFromContext, which falls back to the global logger.

go
// Global logger (defaults to slog.Default())
old := logging.SetLogger(slog.New(slog.NewJSONHandler(os.Stdout, nil)))
defer logging.SetLogger(old)

// Request-scoped logger: install it around the whole pipeline with Local.
// logging.WithLogger(l) is the ctx → Pair[CancelFunc, ctx] arrow that Local expects.
reqLogger := logging.GetLogger().With("requestID", requestID)

value, err := R.Unwrap(F.Pipe1(
    pipeline,
    RIO.Local[Data](logging.WithLogger(reqLogger)),
)(ctx)())

Local exists for context/readerio, context/readerresult and context/statereaderioresult as well. To get a plain enriched context outside a pipeline, use _, ctx2 := pair.Unpack(logging.WithLogger(reqLogger)(ctx)). For a logger stored under your own key, build the callback with F.Flow2(CR.AskValue[*slog.Logger](myKey), O.GetOrElse(slog.Default)). For general context handling see the fp-go-context skill.

Package Overview

PackageLogging API
context/readerioresultTapSLog, TapSLogInfo, TapSLogDebug, SLog*, SLogLeft, SLogRight, SLogWithCallback, LogEntryExit, LogEntryExitWithCallback, MapLeft, Tap*, Local
context/readerresultTapSLog, SLog (Kleisli[Result[A], A]), TapIOK, MapLeft, Local
context/readerioTapSLog, SLog, Tap, TapIOK, Local
ioLogf, LogGo, Printf, PrintGo, Logger: func(A) IO[A], used with TapIOK
readerioLogf, LogGo, Printf, PrintGo for the generic ReaderIO
loggingGetLogger, SetLogger, WithLogger, GetLoggerFromContext, LoggingCallbacks
errorsOnError (wrap with context), OnNone, OnSome (build errors)

SLogWithCallback[A](level, cb, msg) has the shape of SLog. Turn it into an operator with RIOC.Tap(...) (context/readerio) when you need TapSLog with a custom level and logger.

Complete Example

go
func loadUser(id int) RIO.ReaderIOResult[User] {
    return F.Pipe3(
        fetchUser(id),
        RIO.TapSLogDebug[User]("fetched user"),              // simple log statement
        RIO.MapLeft[User](ER.OnError("loading user %d", id)), // add context to the error
        RIO.LogEntryExit[User]("loadUser"),                   // entry/exit around the three steps
    )
}

func handleGreeting(reqLogger *slog.Logger, id int) RIO.ReaderIOResult[string] {
    return F.Pipe3(
        loadUser(id),
        RIO.Map(getName),
        RIO.TapLeft[string](RIO.SLogLeft("greeting failed")), // log the error once, at the boundary
        RIO.Local[string](logging.WithLogger(reqLogger)),     // every log above uses reqLogger
    )
}

name, err := R.Unwrap(handleGreeting(reqLogger, 7)(ctx)())

© IBM, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/fp-go-logging of IBM/fp-go.

Open the folder on GitHubat commit 1c4245d

Compare with similar skills

fp-go Logging Patterns next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

fp-go Logging Patterns compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
fp-go Logging Patterns this skillIBM/fp-go2k—~3.7kAutomated safety check: PassApache-2.0
Logging Observabilitygetsentry/toolkit917—~2.6kAutomated safety check: PassCustom licence
Golang Error Handlingunxed/f42413 repos~1.8kAutomated safety check: PassMIT
Deploy Observabilityaliyun/alibabacloud-observability-mcp-server166—~2.6kAutomated safety check: NotesNone
Zodjasonjgardner/blockbench-mcp-plugin4913 repos~1.4kAutomated safety check: PassGPL-3.0
Grepaiyoanbernabeu/grepai1.9k—~1.1kAutomated safety check: PassMIT

Similar skills

  • Logging Observability

    getsentry/toolkit

    Official

    Review code for correct logging and error handling patterns.

    917 GitHub stars~2.6k tokensUpdated today
    DevOps & CloudAuto-check passed
  • Idiomatic Golang error handling — creation, wrapping with %w, errors.Is/As, errors.Join, custom error types, sentinel errors, panic/recover, the single handling rule, structured logging with slog…

    241 GitHub starsUsed in 3 repos~1.8k tokens
    DevOps & CloudAuto-check passed
  • Deploy Observability

    aliyun/alibabacloud-observability-mcp-server

    Deploy, start, and update the Alibaba Cloud Observability MCP Server (阿里云可观测 MCP Server).

    166 GitHub stars~2.6k tokensUpdated 1 mo ago
    DevOps & CloudAuto-check: notes
  • Zod

    jasonjgardner/blockbench-mcp-plugin

    Zod schema validation best practices for type safety, parsing, and error handling.

    491 GitHub starsUsed in 3 repos~1.4k tokens
    DevelopmentAuto-check passed
  • Grepai

    yoanbernabeu/grepai

    Semantic code search and call-graph tracing. An agent skill from yoanbernabeu/grepai.

    1.9k GitHub stars~1.1k tokensUpdated 17 days ago
    DevelopmentAuto-check passed
  • Release

    yoanbernabeu/grepai

    Create a new release for grepai. An agent skill from yoanbernabeu/grepai.

    1.9k GitHub stars~918 tokensUpdated 17 days ago
    DevelopmentAuto-check passed

More from IBM/fp-go

All 10 skills in this repo
  • Official

    Covers handling Go's context.Context idiomatically in fp-go code: reading and scoping context through operators, timeouts, cancellation and converting ctx-first functions.

    2k GitHub stars~4.2k tokensUpdated yesterday
    Auto-check passed
  • Teaches an agent to write fp-go v2 services with the Effect type, carrying dependencies in its type parameter instead of in context.Context or parameters.

    2k GitHub stars~4.3k tokensUpdated yesterday
    Auto-check passed
  • Official

    Shows how to build composable, context-aware HTTP pipelines in Go using fp-go's ReaderIOResult monad instead of raw net/http calls.

    2k GitHub stars~4.4k tokensUpdated yesterday
    Auto-check passed
  • Official

    Generates or hand-writes composable lenses for the fp-go library so nested Go structs can be read and updated immutably.

    2k GitHub stars~4.3k tokensUpdated yesterday
    Auto-check passed
  • Official

    Configures and queries the fp-go MCP server so Claude Code, Claude Desktop or another MCP client can search fp-go's examples and skills directly.

    2k GitHub stars~3.3k tokensUpdated yesterday
    Auto-check passed
  • Official

    Guides writing or reviewing point-free, first-match-wins case lists in fp-go v2 Go code instead of switch statements and if-else chains.

    2k GitHub stars~2.8k tokensUpdated yesterday
    Auto-check passed

Categories

Questions about fp-go Logging Patterns

What does fp-go Logging Patterns do?

Adds logging to fp-go functional pipelines with Tap operators, entry and exit logs and error context, so that logging never changes the value or error flowing through. Logging is treated as a side effect: a `Tap` runs an effect on the current value or error and passes the original computation on unchanged.OnError` and then logging once.

When should I use fp-go Logging Patterns?

fp-go Logging Patterns fits situations like: adding structured slog logging inside an fp-go Pipe or Flow; logging entry and exit of a ReaderIOResult step with timing; attaching context to an error before it is logged once; putting a request-scoped logger into the context for a pipeline.

How do I install fp-go Logging Patterns in Claude Code?

Run `npx skills add IBM/fp-go --skill fp-go-logging -a claude-code`. Or copy the skill folder (skills/fp-go-logging in IBM/fp-go) into .claude/skills/fp-go-logging in your project. Claude Code loads it when a task matches its description.

How do I install fp-go Logging Patterns in Codex?

Run `npx skills add IBM/fp-go --skill fp-go-logging -a codex`. Or copy the skill folder (skills/fp-go-logging in IBM/fp-go) into .agents/skills/fp-go-logging in your project. Codex loads it when a task matches its description.

Can I use fp-go Logging Patterns in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add IBM/fp-go --skill fp-go-logging -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/fp-go-logging, .gemini/skills/fp-go-logging, .github/skills/fp-go-logging and .opencode/skills/fp-go-logging in your project.

What does fp-go Logging Patterns need to run?

Going by SKILL.md and its folder, fp-go Logging Patterns needs the command-line tools its instructions call (go). Our summary lists: Go with the fp-go v2 library; The fp-go MCP server, for looking up combinators.

Does fp-go Logging Patterns access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is fp-go Logging Patterns safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does fp-go Logging Patterns use?

fp-go Logging Patterns is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does fp-go Logging Patterns use?

About 3.7k tokens (SKILL.md is roughly 15k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to fp-go Logging Patterns?

Skills that share tags, products or a category with fp-go Logging Patterns: Logging Observability (getsentry/toolkit, 917 stars), Golang Error Handling (unxed/f4, 241 stars), Deploy Observability (aliyun/alibabacloud-observability-mcp-server, 166 stars) and Zod (jasonjgardner/blockbench-mcp-plugin, 491 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains fp-go Logging Patterns?

IBM (a GitHub organization, an official publisher) maintains it in IBM/fp-go, which has 2,029 GitHub stars. The repository holds 10 skills in this directory. The repository was last updated on October 7, 2026.

Source: IBM/fp-go on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.