gomark

package module
v1.0.23 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 23, 2022 License: Apache-2.0 Imports: 6 Imported by: 0

README

Table of contents generated with markdown-toc

Introduce

GoMark is a tool for system status monitoring and it implements some variables exactly like bvar in brpc, but using go instead of c++.

For more detailed information, see: https://github.com/apache/incubator-brpc/blob/master/docs/en/bvar.md

Usage

Init

gomark monitor variable statistics through HTTP web server, so you need call

StartHTTPServer(port int)

to start HTTP service before using.

Dock gomark to external HTTP server

Maybe you have your own HTTP server and you wish to dock gomark to it instead of create a new one. GoMark actually supports this deployment. You need:

Add routers

GoMark requires the following routers:

	r := mux.NewRouter()
	r.HandleFunc("/vars/js/{script}", procJs) // Route: js
	r.HandleFunc("/vars", procVar) // Route: vars
	r.HandleFunc("/vars/{var}", procVar) // Route: vars
	r.HandleFunc("/vars/debug", procDebug) // Route: debug

Here {xxx} indicates a path variable, like/vars/test_adder or /vars/*adder*.

Note that each router may require additional path parameters in form ?a=b or ?a, like /vars/test_adder?dataonly, here dataonly is a parameter, or /vars/debug?p=1, here p is a parameter.

Both path variables or parameters are stored in gmi.Request along with headers:

type Request struct {
	Router  Route
	Params  map[string]string
	headers map[string]string
}

You need fill them from HTTP request.

Note that for path variable, you need use word inside {} in route definition above as key in Request.Params.

You may note that no URL is required here, that's because Router defines a string to represent above routes, see comments after each definition.

Like gmi.Request, gmi.Response defines all information you need to write into HTTP response, make sure you write them all.

type Response struct {
	Status  int
	headers map[string]string
	Body    []byte
}
Call GoMark on receiving HTTP requests

In your routing handler, you need convert HTTP request to gmi.Request and call gomark.Request, and write returned gmi.Response to HTTP response.

Examples
  1. /vars/js/jquery_min should deliver params: {"script": "jquery_min"}, route: "js", here script comes from path variable definition in route.
  2. /vars/debug?p=1 should deliver params: {"p": "1"}, route: "debug". DO NOT add parameter {"var": "debug"}.
  3. /vars/*latency*,*add*?dataonly&v=1 should deliver params: {"var": "*latency*,*add*", "dataonly":"", "v": "1"}, route: "var". Note here dataonly takes no value and SHOULD NOT be ignored, and var as key comes from path variable definition in route.

Variable Create

A variable is an entity that maintains all information of statistics. There are several variables, and can be created by:

NewLatencyRecorder
NewAdder
NewCounter
NewQPS
NewMaxer
NewWindowMaxer

Each of above will create a variable and returns as gmi.Marker, which is an interface:

// Marker is an interface to provide variable marking.
type Marker interface {
	// Mark a number, the number definition is bound to marker itself.
	Mark(n int32)
	// Stop this marking.
	Cancel()
}

Call Mark to send a marking point to variable and Cancel to stop using(and never use it).

Latency

If you need to use latency recorder and use millisecond as time unit, you may be interested in gmi.Latency. It record a start point of time on creation, and calculate milliseconds since creation on marking. Here is how to use:

// create a latency recorder
lr = gomark.NewLatencyRecorder("test")

// at start point, create a latency with latency recorder
latency = gomark.NewLatency(lr)
// at end point, call Latency.Mark()
latency.Mark()
// Now latency will calculate duration between start point and end point in millisecond
// and call latency recorder to mark

Working with C/CPP

gomark is designed to work on GO. But it also provide an adapter to work with C/CPP.

adapter provide C interfaces to call variable create/mark/cancel of gomark package. It works along with hook, which is a sub-project of gomark compiling to be a dynamic library libgmhook.so for C/CPP users.

This is how it works:

  1. gomark user calls adapter.StartAdapter to enable hook connected with gomark by registering C callbacks to create/mark/cancel variables(register_gm_hook).
  2. C program working with gomark should directly call gm_var_create/gm_var_mark/gm_var_cancel in libgmhook.so to use gomark through adapter(adatper will call registered gomark callbacks).
  3. CPP program working with gomark may delcare GmVariable defined in gmhookpp to use gomark also through adatper.

To use this feature, gomark user need:

  1. make hook and install, see readme
  2. GO program should call adapter.StartAdapter
  3. add these two CGO flags in environment before building to let adapter found libgmhook.so and gmhook.h
export CGO_CFLAGS="-I/path_to_install_of_hook/include"
export CGO_LDFLAGS="-L/path_to_install_of_hook/lib -lgmhook"

Example

example shows how to use adder and latency recorder. Actually all variables are used in the same way:

  1. create
  2. mark int32 values
  3. cancel

Monitor

Visit http://ip:port/vars to monitor system statistics.

This is how it looks like:

image

You may click those clickable records, and you will see:

image

Performance

Test method: in one goroutine, continuouesly marking for 10 million marks, get the time elasped and calculate how many marks can be done in one second(QPS).

updated 2020.11.19

Variable QPS
MaxWindow 6214338
Maxer 6497730
Adder 6445707
LatencyRecorder 5411037
QPS 6837910
Counter 6163937

Test

cmd/main/gomark.go is used run tests. It use glog for logging, so add -stderrthreshold=INFO in command line:

go run gomark.go -stderrthreshold=INFO 

Read the usage and run test.

TODOs

  1. Provide interface for Prometheus

Documentation

Overview

Package gomark runs an HTTP server for markable variables.

A variable is a gmi.Marker that provides a single kind of monitor and expose their markings through HTTP request: http://ip:port/vars.

After variable is created, user may call Mark() to push a number. The definition of number depends what kind of variable you create.

If you want to destroy variable, call Cancel(), after which variable can not be used.

Both Mark() and Cancel() are sync call and are safe cross routines.

gomark is actually a go verison of bvar, see:

https://github.com/apache/incubator-brpc

for more information.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DisableServer added in v1.0.22

func DisableServer()

DisableServer will make server reject all marks

func EnableServer added in v1.0.22

func EnableServer()

EnableServer will make server accept all marks

func IntToMarker

func IntToMarker(id int) gmi.Marker

func NewAdder

func NewAdder(name string) gmi.Marker

NewAdder create an adder with series.

func NewAdderPerSecond

func NewAdderPerSecond(name string) gmi.Marker

func NewCounter

func NewCounter(name string) gmi.Marker

NewCounter provide a passive status for counter. I prefer you use NewAdder instead.

func NewLatencyRecorder

func NewLatencyRecorder(name string) gmi.Marker

NewLatencyRecorder create a latency recorder.

func NewMaxer

func NewMaxer(name string) gmi.Marker

NewMaxer saves max value(no series)

func NewPercentile

func NewPercentile() interface {
	Push(v gm.Mark)
	Dispose()
}

NewPercentile create a percentile collector.

func NewQPS

func NewQPS(name string) gmi.Marker

NewQPS provide QPS statistics.

func NewStatus

func NewStatus(name string) gmi.Marker

func NewWindowMaxer

func NewWindowMaxer(name string) gmi.Marker

NewWindowMaxer collects max values in each period.

func Request

func Request(req *gmi.Request) *gmi.Response

Request will docker gomark to your own http server See http_server.go for detailed information, there Start() will start an http server based on mux, and it will call the same API as this calls.

func StartHTTPServer

func StartHTTPServer(port int)

StartHTTPServer will create an http server for gomark.

Types

type Latency

type Latency struct {
	// contains filtered or unexported fields
}

Latency provide a convenient way to record a single latency. It is bound with a latency recorder which is provided at creation

func NewLatency

func NewLatency(marker gmi.Marker) *Latency

NewLatency create a latency for a Latency Recorder created by NewLatencyRecorder.

func (*Latency) Cancel

func (l *Latency) Cancel()

Cancel will clear this latency and it will not be able to use any more.

func (*Latency) Latency added in v1.0.13

func (l *Latency) Latency() int32

func (*Latency) Mark

func (l *Latency) Mark()

Mark calculate how many ms has passed since creation of this Latency and mark it.

Directories

Path Synopsis
cmd
Package gmi defines Marker to represent each variable by interface.
Package gmi defines Marker to represent each variable by interface.
internal
gm

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL