API Guide
The example code in this document is available in the github.com/whatap/go-api-example repository.
Download
Download the package and the related dependencies.
go get github.com/whatap/go-api
Getting started
init, shutdown
Start the monitoring module by using the trace.Init()
function. defer trace.Shutdown()
makes sure that the monitoring ends.
import "github.com/whatap/go-api/trace"
func main(){
trace.Init(nil)
//It must be executed before closing the app.
defer trace.Shutdown()
...
}
func Init(m map[string]string)
This can be set in the initial stage of the application by declaring it in the form of map[string]string
. Otherwise, more settings can be added in whatap.conf. The performance information can be sent to the WhaTap collection server only when TCP connection to the agent is established normally. It performs TCP communication via 127.0.0.1:6600 using the basic connection information.
To change the connection information, pass the settings to the Init
function, or set them in the whatap.conf file and then restart the application.
m := make(map[string]string)
m["net_ipc_host"] = "127.0.0.1"
m["net_ipc_port"] = "6601"
trace.Init(m)
accesskey={access key}
whatap.server.host={collection server IP}
net_ipc_host=127.0.0.1
net_ipc_host=6600
Context
The agents collect performance data based on the transaction. The transactions are classified based on the context
to which whatap context(trace.TraceCtx)
belongs. The performance data that is not related to transactions is ignored or collected only as statistical data.
Generating transactions
The whatap context
is generated by the Start
and StartWithReqest
functions of the go-api/trace
module. Set the TraceCtx
data with the whatap
key in the context
.
var traceCtx *TraceCtx
traceCtx.Txid = keygen.Next()
ctx = context.WithValue(ctx, "whatap", traceCtx)
In APIs for transactions, SQLs, DBConnections, external HTTP requests, and general function tracing, the Context
in which the TraceCtx
object exists as the whatap
key is required at startup.
Transaction tracing
It traces all transactions from web requests to responses, and traces transactions for normal work units. It consists of the startup and end functions. It is recognized as a single transaction, and you can see the detailed views on the hitmap widget and the statistical metrics such as TPS, response time, and average response time.
You can collect HTTP parameters and HTTP headers through the settings.
Web transaction trace
http.HandleFunc("/index", func(w http.ResponseWriter, r *http.Request) {
ctx, _ := trace.StartWithRequest(r)
defer trace.End(ctx, nil)
}
-
trace.Func()
,trace.HandlerFunc()
-
Function that wraps Handle and HandFunc of the
net/http
-
Proceed with
trace.StartWithRequest
andtrace.End
in the same way. -
The name of the web transaction is set to RequestURI.
-
-
trace.Step()
It provides the function to output the strings delivered by the user to the profile data.
Gohttp.HandleFunc("/wrapHandleFunc", trace.Func(func(w http.ResponseWriter, r *http.Request) {
...
}))Gohttp.Handle("/wrapHandleFunc1", trace.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
...
}))
General transaction trace
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 connection and SQL tracing
Execution times and errors can be collected by passing parameters for DB connection, SQL syntax, errors, and prepared statements to the API. SQL statements can be collected up to 32 KB. The parameters for SQL prepared statements are collected up to 20 and up to 256 bytes for each.
DB Connection
import (
whatapsql "github.com/whatap/go-api/sql"
)
func main(){
trace.Init(nil)
//It must be executed before closing the app.
defer trace.Shutdown()
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()
}
import (
whatapsql "github.com/whatap/go-api/sql"
)
func main(){
trace.Init(nil)
//It must be executed before closing the app.
defer trace.Shutdown()
ctx, _ := trace.Start(context.Background(), "Trace Query")
defer trace.End(ctx, nil)
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)
}
import (
whatapsql "github.com/whatap/go-api/sql"
)
func main(){
trace.Init(nil)
//It must be executed before closing the app.
defer trace.Shutdown()
ctx, _ := trace.Start(context.Background(), "Trace Prepared Statement")
defer trace.End(ctx, nil)
// Create Prepared Statement
query = "select id, subject from tbl_faq where id = ? limit ?"
stmt, err := db.Prepare(query)
if err != nil {
return
}
defer stmt.Close()
params := make([]interface{}, 0)
params = append(params, 8)
params = append(params, 1)
sqlCtx, _ := whatapsql.StartWithParamArray(ctx, "id:pwd(x.x.x.x:3306)/test", query, params)
rows, err := stmt.QueryContext(ctx, params...)
whatapsql.End(sqlCtx, err)
sqlCtx, _ = whatapsql.StartWithParam(ctx, "id:pwd(x.x.x.x:3306)/test", query, params...)
rows, err := stmt.QueryContext(ctx, params...)
whatapsql.End(sqlCtx, err)
}
Database/SQL package configuration
Use the whatapsql.OpenContext
function instead of the sql.Open
function of the database/sql package. It is recommended to use the functions that pass the contexts
, such as PrepareContext
, QueryContext
, and ExecContext
. The context
to be delivered must have the whatap TraceCtx data through trace.Start()
.
import (
_ "github.com/go-sql-driver/mysql"
"github.com/whatap/go-api/instrumentation/database/sql/whatapsql"
)
func main() {
config := make(map[string]string)
trace.Init(config)
defer trace.Shutdown()
// The whatap TraceCtx is generated inside whataphttp.Func.
http.HandleFunc("/query", whataphttp.Func(func(w http.ResponseWriter, r *http.Request){
ctx := r.Context()
// Use the WhaTap Driver. It passes the contexts that have TraceCtx.
db, err := whatapsql.OpenContext(ctx, "mysql", dataSource)
if err != nil {
fmt.Println("Error whatapsql.Open ", err)
return
}
defer db.Close()
...
query := "select id, subject from tbl_faq limit 10"
// It passes the contexts that have TraceCtx.
if rows, err := db.QueryContext(ctx, query); err == nil {
...
}
}
...
}
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
Tracing the HTTP requests
import (
"github.com/whatap/go-api/httc"
)
func main(){
trace.Init(nil)
//It must be executed before closing the app.
defer trace.Shutdown()
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 RoundTripper
You can set up the RoundTripper.
import (
"github.com/whatap/go-api/instrumentation/net/http/whataphttp"
)
func main() {
config := make(map[string]string)
trace.Init(config)
defer trace.Shutdown()
ctx, _ := trace.Start(context.Background(), "Http call")
defer trace.End(ctx, nil)
callUrl := "http://aaa.com/xxx"
client := http.DefaultClient
// Use WhaTap RoundTripper. It passes the contexts that have TraceCtx.
client.Transport = whataphttp.NewRoundTrip(ctx, http.DefaultTransport)
resp, err := client.Get(callUrl)
if err != nil {
...
}
defer resp.Body.Close()
...
}
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
Function tracing
This API measures the execution time of the user function or desired section. API can be set before or after execution of the function.
import (
"github.com/whatap/go-api/method"
)
func main(){
trace.Init(nil)
//It must be executed before closing the app.
defer trace.Shutdown()
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