본문으로 건너뛰기

수동 적용 가이드

Go 라이브러리를 이용해 와탭 에이전트에 모니터링할 데이터를 수동으로 전송할 수 있습니다. 예제 코드는 github.com/whatap/go-api-example에서 확인할 수 있습니다.

노트

자동 적용 vs 수동 적용

  • 자동 적용 (권장): 자동 적용 가이드를 참조하여 코드 자동 삽입
  • 수동 적용: 이 문서에서 설명하는 API를 직접 코드에 추가

시작하기​

다음 명령어로 Go API를 설치하세요.

go get github.com/whatap/go-api@latest

Init, Shutdown​

모니터링 모듈을 초기화하고 종료하는 기본 구조:

import "github.com/whatap/go-api/trace"

func main(){
trace.Init(nil)
defer trace.Shutdown()
...
}

Init 함수의 설정 옵션:

  • map[string]string 형식으로 초기 설정 가능
  • whatap.conf 파일에서도 설정 가능
  • 기본 TCP 연결: 127.0.0.1:6600
m := make(map[string]string)
m["net_ipc_host"] = "127.0.0.1"
m["net_ipc_port"] = "6601"
trace.Init(m)

whatap.conf 설정:

accesskey={액세스 키}
whatap.server.host={수집 서버 IP 주소}
net_ipc_host=127.0.0.1
net_ipc_port=6600

Context 관리​

에이전트는 whatap context(trace.TraceCtx)를 기준으로 트랜잭션을 구분합니다. 트랜잭션 외의 성능 정보는 무시되거나 통계만 수집됩니다.

트랜잭션 생성​

var traceCtx *TraceCtx
traceCtx.Txid = keygen.Next()
ctx = context.WithValue(ctx, "whatap", traceCtx)

트랜잭션 추적​

웹 트랜잭션 추적​

http.HandleFunc("/index", func(w http.ResponseWriter, r *http.Request) {
ctx, _ := trace.StartWithRequest(r)
defer trace.End(ctx, nil)
})

래핑 함수:

  • trace.Func(): RequestURI를 트랜잭션 이름으로 설정
  • trace.HandlerFunc(): 동일 기능 제공

일반 트랜잭션 추적​

func main() {
ctx := context.Background()
ctx, _ := trace.Start(ctx, "Custom Transaction")
...
trace.End(ctx, nil)
}

트랜잭션 API​

func Start(ctx context.Context, name string) (context.Context, error)
func End(ctx context.Context, err error) error
func StartWithRequest(r *http.Request) (context.Context, error)
func Step(ctx context.Context, title, message string, elapsed, value int) error
func HandlerFunc(handler func(http.ResponseWriter, *http.Request)) http.HandlerFunc
func Func(handler func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request)

DB 연결 및 SQL 추적​

제한사항:

  • SQL 구문: 최대 32KB
  • Prepared 파라미터: 최대 20개, 각 256byte

DB Connection 추적​

import whatapsql "github.com/whatap/go-api/sql"

ctx, _ := trace.Start(context.Background(), "Trace Open DB")
defer trace.End(ctx, nil)

sqlCtx, _ := whatapsql.StartOpen(ctx, "id@tcp(x.x.x.x:3306)/test")
db, err := sql.Open("mysql", "id:pwd@tcp(x.x.x.x:3306)/test")
whatapsql.End(sqlCtx, err)
defer db.Close()

SQL Query 추적​

query = "select id, subject from tbl_faq limit 10"
sqlCtx, _ = whatapsql.Start(ctx, "id:pwd@tcp(x.x.x.x:3306)/test", query)
rows, err := db.QueryContext(ctx, query)
whatapsql.End(sqlCtx, err)

Prepared Statement 추적​

query = "select id, subject from tbl_faq where id = ? limit ?"
stmt, err := db.Prepare(query)
defer stmt.Close()

params := make([]interface{}, 0)
params = append(params, 8)
params = append(params, 1)

sqlCtx, _ := whatapsql.StartWithParamArray(ctx, "id:pwd@tcp(x.x.x.x:3306)/test", query, params)
rows, err := stmt.QueryContext(ctx, params...)
whatapsql.End(sqlCtx, err)

database/sql 패키지 활용​

import (
_ "github.com/go-sql-driver/mysql"
"github.com/whatap/go-api/instrumentation/database/sql/whatapsql"
)

db, err := whatapsql.OpenContext(ctx, "mysql", dataSource)
defer db.Close()

if rows, err := db.QueryContext(ctx, query); err == nil {
...
}

SQL API​

func Start(ctx context.Context, dbhost, sql string) (*SqlCtx, error)
func StartOpen(ctx context.Context, dbhost string) (*SqlCtx, error)
func End(sqlCtx *SqlCtx, err error) error
func StartWithParam(ctx context.Context, dbhost, sql, param ...interface{}) (*SqlCtx, error)
func StartWithParamArray(ctx context.Context, dbhost, sql string, param []interface{}) (*SqlCtx, error)
func Trace(ctx context.Context, dbhost, sql, param string, elapsed int, err error) error

HTTP 요청 추적​

import "github.com/whatap/go-api/httc"

ctx, _ := trace.Start(context.Background(), "Trace Http Call")
defer trace.End(ctx, nil)

httpcCtx, _ := httpc.Start(ctx, callUrl)
resp, err := http.Get(callUrl)
if err == nil {
httpc.End(httpcCtx, resp.StatusCode, "", nil)
} else {
httpc.End(httpcCtx, 0, "", err)
}

HTTP Transport RoundTrip​

import "github.com/whatap/go-api/instrumentation/net/http/whataphttp"

ctx, _ := trace.Start(context.Background(), "Http call")
defer trace.End(ctx, nil)

client := http.DefaultClient
client.Transport = whataphttp.NewRoundTrip(ctx, http.DefaultTransport)
resp, err := client.Get(callUrl)
defer resp.Body.Close()

HTTP API​

func Start(ctx context.Context, url string) (*HttpcCtx, error)
func End(httpcCtx *HttpcCtx, status int, reason string, err error) error
func Trace(ctx context.Context, host string, port int, url string, elapsed int, status int, reason string, err error) error

멀티 트랜잭션 추적 (분산 추적)​

다른 에이전트나 프로젝트와 연관된 트랜잭션을 추적합니다.

헤더 키값:

  • x-wtap-po
  • x-wtap-mst
  • x-wtap-sp1

또한 OpenTrace의 traceparent 헤더도 지원합니다.

에이전트 설정​

mtrace_enabled=true
mtrace_rate=100

Request Header 처리​

func UpdateMtrace(traceCtx *trace.TraceCtx, header http.Header)

trace.StartWithRequest는 내부적으로 이 함수를 호출합니다.

ctx, traceCtx := trace.GetTraceContext(ctx)
if traceCtx != nil {
trace.UpdateMtrace(traceCtx, header)
}

Header 정보 조회 및 추가​

func GetMTrace(ctx context.Context) http.Header

이 함수는 분산 추적에 필요한 Header를 반환합니다:

headers := trace.GetMTrace(wCtx)
for key, _ := range headers {
req.Header.Set(key, headers.Get(key))
}

자동 Header 추가​

WhaTap transport에 이미 포함되어 있습니다:

client := http.Client{Timeout: timeout}
client.Transport = whataphttp.NewRoundTrip(ctx, http.DefaultTransport)
resp, err := client.Get(callUrl)

다중 Transport 사용:

client.Transport = NewAccessLogRoundTrip(whataphttp.NewRoundTrip(ctx, http.DefaultTransport))

함수 추적​

사용자 함수 또는 특정 구간의 실행 시간 측정:

import "github.com/whatap/go-api/method"

ctx, _ := trace.Start(context.Background(), "Trace Method")
defer trace.End(ctx, nil)

getUser(ctx)

func getUser(ctx context.Context) {
methodCtx, _ := method.Start(ctx, "getUser")
defer method.End(methodCtx, nil)
time.Sleep(time.Duration(1) * time.Second)
}

함수 추적 API​

func Start(ctx context.Context, name string) (*MethodCtx, error)
func End(methodCtx *MethodCtx, err error) error
func Trace(ctx context.Context, name string, elapsed int, err error) error

Wrap 함수 (Go 1.18+ Generics)​

Wrap 함수들은 클로저를 사용하여 계측 코드를 간결하게 작성할 수 있게 해줍니다. Go 1.18 이상의 Generics를 활용합니다.

Trace Wrap 함수 (범용)​

특정 도메인에 속하지 않는 범용 추적에 사용합니다.

import "github.com/whatap/go-api/trace"

// Wrap - (T, error) 반환하는 범용 함수
result, err := trace.Wrap(ctx, "ThirdParty.Calculate", func() (int, error) {
return thirdPartyLib.Calculate(input)
})

// WrapError - error만 반환
err := trace.WrapError(ctx, "FileProcessor.Process", func() error {
return processFile(path)
})

// WrapVoid - 반환값 없음
trace.WrapVoid(ctx, "Cleanup.Execute", func() {
cleanup()
})

SQL Wrap 함수​

Hook을 지원하지 않는 DB 라이브러리 (Aerospike, 일부 NoSQL 등) 계측에 유용합니다.

import "github.com/whatap/go-api/sql"

// Wrap - (T, error) 반환하는 쿼리
record, err := sql.Wrap(ctx, "aerospike://host:3000", "GET ns/set", func() (*aero.Record, error) {
return client.Get(policy, key)
})

// WrapError - error만 반환하는 쿼리 (INSERT, UPDATE, DELETE)
err := sql.WrapError(ctx, "aerospike://host:3000", "PUT ns/set", func() error {
return client.Put(policy, key, bins)
})

// WrapP - 파라미터 추적 포함
rows, err := sql.WrapP(ctx, "mysql://host:3306", "SELECT * FROM users WHERE id = ?",
[]interface{}{userId},
func() (*sql.Rows, error) {
return db.Query("SELECT * FROM users WHERE id = ?", userId)
},
)

// WrapOpen - DB 연결 추적
db, err := sql.WrapOpen(ctx, "mysql://host:3306", func() (*sql.DB, error) {
return sql.Open("mysql", dsn)
})

HTTP Wrap 함수​

외부 HTTP API 호출 계측에 사용합니다.

import "github.com/whatap/go-api/httpc"

// Wrap - (T, error) 반환
resp, err := httpc.Wrap(ctx, "https://api.payment.com/charge", func() (*PaymentResp, error) {
return paymentClient.Charge(amount)
})

// WrapError - error만 반환
err := httpc.WrapError(ctx, "https://api.example.com/webhook", func() error {
return sendWebhook(payload)
})

// WrapWithStatus - HTTP 상태 코드 포함
resp, status, err := httpc.WrapWithStatus(ctx, "https://api.example.com/data",
func() (*Response, int, error) {
resp, err := client.Get(url)
if resp != nil {
return resp, resp.StatusCode, err
}
return nil, 0, err
},
)

Method Wrap 함수​

사용자 정의 메서드/함수 추적에 사용합니다.

import "github.com/whatap/go-api/method"

// Wrap - (T, error) 반환
order, err := method.Wrap(ctx, "OrderService.ProcessOrder", func() (*Order, error) {
return s.processOrderInternal(orderID)
})

// WrapError - error만 반환
err := method.WrapError(ctx, "OrderService.ValidateOrder", func() error {
return s.validateOrder(order)
})

// WrapVoid - 반환값 없음
method.WrapVoid(ctx, "CacheService.Invalidate", func() {
s.cache.Delete(key)
})

Wrap 함수 API 요약​

패키지함수설명
traceWrap[T]범용 (T, error) 반환
traceWrapError범용 error만 반환
traceWrapVoid범용 반환값 없음
sqlWrap[T](T, error) 반환 쿼리
sqlWrapErrorerror만 반환 쿼리
sqlWrapP[T]파라미터 추적 포함
sqlWrapErrorP파라미터 + error만
sqlWrapOpen[T]DB 연결 추적
httpcWrap[T]HTTP 호출
httpcWrapErrorerror만 반환
httpcWrapWithStatus[T]상태 코드 포함
methodWrap[T]메서드 추적
methodWrapErrorerror만 반환
methodWrapVoid반환값 없음

로그 수집​

에이전트 설정​

logsink_enabled=true              # 로그 수집 활성화 (기본: false)
logsink_trace_enabled=true # 트랜잭션 연계 (기본: true)
logsink_zip_enabled=true # 압축 전송 (기본: true)

TraceLogWriter (권장)​

logsink.GetTraceLogWriter()를 사용하면 로그와 트랜잭션을 연계할 수 있습니다. 로그에 @txid, @mtid, @gid 필드가 자동으로 추가됩니다.

func GetTraceLogWriter(w io.Writer) io.Writer
func GetTraceLogWriterWithCategory(w io.Writer, category string) io.Writer

변경 안내: 기존 GetWriterHookStdout(), GetWriterHookStderr() 대신 GetTraceLogWriter(os.Stdout), GetTraceLogWriter(os.Stderr) 사용을 권장합니다.

기존 API (호환성 유지)​

func GetWriterHookStdout() io.Writer  // → GetTraceLogWriter(os.Stdout) 권장
func GetWriterHookStderr() io.Writer // → GetTraceLogWriter(os.Stderr) 권장

log package 예제​

import (
"log"
"os"
"github.com/whatap/go-api/logsink"
"github.com/whatap/go-api/trace"
)

func main() {
trace.Init(nil)
defer trace.Shutdown()

// 권장: TraceLogWriter 사용
log.SetOutput(logsink.GetTraceLogWriter(os.Stderr))

// 기존 방식 (호환성 유지)
// log.SetOutput(logsink.GetWriterHookStderr())

log.Println("Application started")
}

go.uber.org/zap 예제​

import (
"os"
"github.com/whatap/go-api/logsink"
"github.com/whatap/go-api/trace"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)

func main() {
trace.Init(nil)
defer trace.Shutdown()

// TraceLogWriter로 래핑
writer := logsink.GetTraceLogWriter(os.Stdout)

consoleCore := zapcore.NewCore(
zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()),
zapcore.AddSync(writer),
zap.InfoLevel,
)
logger := zap.New(consoleCore)
logger.Info("logger started")
}

sirupsen/logrus 예제​

import (
"os"
log "github.com/sirupsen/logrus"
"github.com/whatap/go-api/logsink"
"github.com/whatap/go-api/trace"
)

func main() {
trace.Init(nil)
defer trace.Shutdown()

// TraceLogWriter로 래핑
log.SetOutput(logsink.GetTraceLogWriter(os.Stderr))
log.Info("Log message")
}

웹 프레임워크 계측​

instrumentation 패키지를 사용하면 주요 웹 프레임워크에 대한 자동 추적이 가능합니다.

Gin​

import (
"github.com/gin-gonic/gin"
"github.com/whatap/go-api/instrumentation/github.com/gin-gonic/gin/whatapgin"
)

func main() {
trace.Init(nil)
defer trace.Shutdown()

r := gin.Default()
r.Use(whatapgin.Middleware())

r.GET("/hello", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "hello"})
})
r.Run(":8080")
}

Echo v4​

import (
"github.com/labstack/echo/v4"
"github.com/whatap/go-api/instrumentation/github.com/labstack/echo/v4/whatapecho"
)

func main() {
trace.Init(nil)
defer trace.Shutdown()

e := echo.New()
e.Use(whatapecho.Middleware())

e.GET("/hello", func(c echo.Context) error {
return c.JSON(200, map[string]string{"message": "hello"})
})
e.Start(":8080")
}

Fiber v2​

import (
"github.com/gofiber/fiber/v2"
"github.com/whatap/go-api/instrumentation/github.com/gofiber/fiber/v2/whatapfiber"
)

func main() {
trace.Init(nil)
defer trace.Shutdown()

app := fiber.New()
app.Use(whatapfiber.Middleware())

app.Get("/hello", func(c *fiber.Ctx) error {
return c.JSON(fiber.Map{"message": "hello"})
})
app.Listen(":8080")
}

Chi v5​

import (
"net/http"
"github.com/go-chi/chi/v5"
"github.com/whatap/go-api/instrumentation/github.com/go-chi/chi/whatapchi"
)

func main() {
trace.Init(nil)
defer trace.Shutdown()

r := chi.NewRouter()
r.Use(whatapchi.Middleware)

r.Get("/hello", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello"))
})
http.ListenAndServe(":8080", r)
}

Gorilla Mux​

import (
"net/http"
"github.com/gorilla/mux"
"github.com/whatap/go-api/instrumentation/github.com/gorilla/mux/whatapmux"
)

func main() {
trace.Init(nil)
defer trace.Shutdown()

r := mux.NewRouter()
r.Use(whatapmux.Middleware)

r.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello"))
})
http.ListenAndServe(":8080", r)
}

FastHTTP​

import (
"github.com/valyala/fasthttp"
"github.com/whatap/go-api/instrumentation/github.com/valyala/fasthttp/whatapfasthttp"
)

func main() {
trace.Init(nil)
defer trace.Shutdown()

handler := func(ctx *fasthttp.RequestCtx) {
ctx.WriteString("hello")
}

fasthttp.ListenAndServe(":8080", whatapfasthttp.Middleware(handler))
}

net/http 핸들러 래핑​

import (
"net/http"
"github.com/whatap/go-api/instrumentation/net/http/whataphttp"
)

func main() {
trace.Init(nil)
defer trace.Shutdown()

// HandleFunc 래핑
http.HandleFunc("/api", whataphttp.Func(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello"))
}))

// Handler 래핑
http.Handle("/handler", whataphttp.Handler(myHandler))

http.ListenAndServe(":8080", nil)
}

database/sql 계측 (whatapsql)​

database/sql 패키지를 래핑하여 자동으로 SQL 쿼리를 추적합니다.

import (
_ "github.com/go-sql-driver/mysql"
"github.com/whatap/go-api/instrumentation/database/sql/whatapsql"
"github.com/whatap/go-api/trace"
)

func main() {
trace.Init(nil)
defer trace.Shutdown()

// sql.Open 대신 whatapsql.Open 사용
db, err := whatapsql.Open("mysql", "user:password@tcp(localhost:3306)/dbname")
if err != nil {
panic(err)
}
defer db.Close()

// 이후 db.Query, db.Exec 등이 자동으로 추적됨
rows, err := db.QueryContext(ctx, "SELECT * FROM users WHERE id = ?", 1)
}

OpenContext (트랜잭션 컨텍스트 연결)​

// 트랜잭션 컨텍스트와 연결
db, err := whatapsql.OpenContext(ctx, "mysql", dsn)

sqlx 계측​

import (
"github.com/whatap/go-api/instrumentation/github.com/jmoiron/sqlx/whatapsqlx"
)

func main() {
trace.Init(nil)
defer trace.Shutdown()

// sqlx.Open 대신 whatapsqlx.Open 사용
db, err := whatapsqlx.Open("mysql", dsn)

// sqlx.Connect 대신 whatapsqlx.Connect 사용
db, err := whatapsqlx.Connect("postgres", dsn)
}

GORM 계측​

gorm.io/gorm (GORM v2)​

import (
"gorm.io/driver/mysql"
"github.com/whatap/go-api/instrumentation/github.com/go-gorm/gorm/whatapgorm"
)

func main() {
trace.Init(nil)
defer trace.Shutdown()

// gorm.Open 대신 whatapgorm.Open 사용
db, err := whatapgorm.Open(mysql.Open(dsn), &gorm.Config{})
}

github.com/jinzhu/gorm (GORM v1)​

import (
"github.com/whatap/go-api/instrumentation/github.com/jinzhu/gorm/whatapgorm"
)

func main() {
trace.Init(nil)
defer trace.Shutdown()

db, err := whatapgorm.Open("mysql", dsn)
}

Redis 계측​

go-redis v9​

import (
"github.com/whatap/go-api/instrumentation/github.com/redis/go-redis/v9/whatapgoredis"
)

func main() {
trace.Init(nil)
defer trace.Shutdown()

// redis.NewClient 대신 whatapgoredis.NewClient 사용
rdb := whatapgoredis.NewClient(&redis.Options{
Addr: "localhost:6379",
})

// redis.NewClusterClient
cluster := whatapgoredis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{"localhost:7000", "localhost:7001"},
})
}

go-redis v8​

import (
"github.com/whatap/go-api/instrumentation/github.com/go-redis/redis/v8/whatapgoredis"
)

// v9과 동일한 사용법
rdb := whatapgoredis.NewClient(&redis.Options{
Addr: "localhost:6379",
})

Redigo​

import (
"github.com/whatap/go-api/instrumentation/github.com/gomodule/redigo/whatapredigo"
)

func main() {
trace.Init(nil)
defer trace.Shutdown()

// redis.Dial 대신 whatapredigo.Dial 사용
conn, err := whatapredigo.Dial("tcp", "localhost:6379")
defer conn.Close()

// 일반적인 redis 명령어 사용
conn.Do("SET", "key", "value")
}

MongoDB 계측​

import (
"go.mongodb.org/mongo-driver/mongo"
"github.com/whatap/go-api/instrumentation/go.mongodb.org/mongo-driver/mongo/whatapmongo"
)

func main() {
trace.Init(nil)
defer trace.Shutdown()

// mongo.Connect 대신 whatapmongo.Connect 사용
client, err := whatapmongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
defer client.Disconnect(ctx)

collection := client.Database("test").Collection("users")
collection.FindOne(ctx, bson.M{"name": "john"})
}

gRPC 계측​

서버 측​

import (
"google.golang.org/grpc"
"github.com/whatap/go-api/instrumentation/google.golang.org/grpc/whatapgrpc"
)

func main() {
trace.Init(nil)
defer trace.Shutdown()

// Interceptor 추가
server := grpc.NewServer(
grpc.UnaryInterceptor(whatapgrpc.UnaryServerInterceptor()),
grpc.StreamInterceptor(whatapgrpc.StreamServerInterceptor()),
)

// 서비스 등록 및 서버 시작
pb.RegisterMyServiceServer(server, &myService{})
server.Serve(lis)
}

클라이언트 측​

func main() {
trace.Init(nil)
defer trace.Shutdown()

conn, err := grpc.Dial("localhost:50051",
grpc.WithInsecure(),
grpc.WithUnaryInterceptor(whatapgrpc.UnaryClientInterceptor()),
grpc.WithStreamInterceptor(whatapgrpc.StreamClientInterceptor()),
)
defer conn.Close()

client := pb.NewMyServiceClient(conn)
resp, err := client.MyMethod(ctx, &pb.Request{})
}

Kafka 계측 (Sarama)​

import (
"github.com/IBM/sarama"
"github.com/whatap/go-api/instrumentation/github.com/IBM/sarama/whatapsarama"
)

func main() {
trace.Init(nil)
defer trace.Shutdown()

config := sarama.NewConfig()

// Producer 래핑
producer, err := sarama.NewSyncProducer(brokers, config)
wrappedProducer := whatapsarama.WrapSyncProducer(producer)

// Consumer 래핑
consumer, err := sarama.NewConsumer(brokers, config)
wrappedConsumer := whatapsarama.WrapConsumer(consumer)
}

Kubernetes client-go 계측​

import (
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"github.com/whatap/go-api/instrumentation/k8s.io/client-go/kubernetes/whatapkubernetes"
)

func main() {
trace.Init(nil)
defer trace.Shutdown()

config, err := rest.InClusterConfig()
if err != nil {
panic(err)
}

// config 래핑
config = whatapkubernetes.WrapConfig(config)

clientset, err := kubernetes.NewForConfig(config)
// 이후 Kubernetes API 호출이 자동으로 추적됨
}

Instrumentation 패키지 요약​

분류패키지Import 경로
웹 프레임워크Gingithub.com/whatap/go-api/instrumentation/github.com/gin-gonic/gin/whatapgin
Echo v4github.com/whatap/go-api/instrumentation/github.com/labstack/echo/v4/whatapecho
Fiber v2github.com/whatap/go-api/instrumentation/github.com/gofiber/fiber/v2/whatapfiber
Chigithub.com/whatap/go-api/instrumentation/github.com/go-chi/chi/whatapchi
Gorilla Muxgithub.com/whatap/go-api/instrumentation/github.com/gorilla/mux/whatapmux
FastHTTPgithub.com/whatap/go-api/instrumentation/github.com/valyala/fasthttp/whatapfasthttp
net/httpgithub.com/whatap/go-api/instrumentation/net/http/whataphttp
데이터베이스database/sqlgithub.com/whatap/go-api/instrumentation/database/sql/whatapsql
sqlxgithub.com/whatap/go-api/instrumentation/github.com/jmoiron/sqlx/whatapsqlx
GORM v2github.com/whatap/go-api/instrumentation/github.com/go-gorm/gorm/whatapgorm
GORM v1github.com/whatap/go-api/instrumentation/github.com/jinzhu/gorm/whatapgorm
Redisgo-redis v9github.com/whatap/go-api/instrumentation/github.com/redis/go-redis/v9/whatapgoredis
go-redis v8github.com/whatap/go-api/instrumentation/github.com/go-redis/redis/v8/whatapgoredis
Redigogithub.com/whatap/go-api/instrumentation/github.com/gomodule/redigo/whatapredigo
NoSQLMongoDBgithub.com/whatap/go-api/instrumentation/go.mongodb.org/mongo-driver/mongo/whatapmongo
RPCgRPCgithub.com/whatap/go-api/instrumentation/google.golang.org/grpc/whatapgrpc
메시지큐Sarama (IBM)github.com/whatap/go-api/instrumentation/github.com/IBM/sarama/whatapsarama
Sarama (Shopify)github.com/whatap/go-api/instrumentation/github.com/Shopify/sarama/whatapsarama
클라우드Kubernetesgithub.com/whatap/go-api/instrumentation/k8s.io/client-go/kubernetes/whatapkubernetes