Skip to content

Commit

Permalink
adapt to pingcap-incubator (#1)
Browse files Browse the repository at this point in the history
Signed-off-by: zhongzc <[email protected]>
  • Loading branch information
zhongzc authored Jun 19, 2020
1 parent dee15e7 commit a9c25a8
Show file tree
Hide file tree
Showing 11 changed files with 80 additions and 15 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: CI

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
build:
strategy:
matrix:
go-version: [1.13.x, 1.14.x]
platform: [ubuntu-latest, macos-latest]

runs-on: ${{ matrix.platform }}

steps:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v2
- name: Test
run: go test ./...
- name: Bench
run: go test -bench=./...
3 changes: 3 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Contribution Guide

Please refer to PingCAP [CONTRIBUTING.md](https://github.com/pingcap/community/blob/master/CONTRIBUTING.md)
3 changes: 3 additions & 0 deletions OWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
committers:
# TODO: in your repo created from this template, you should list the
# project committers below
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
# minitrace-go
# Minitrace-go
[![Actions Status](https://github.com/pingcap-incubator/minitrace-go/workflows/CI/badge.svg)](https://github.com/pingcap-incubator/minitrace-go/actions)
[![LICENSE](https://img.shields.io/github/license/pingcap-incubator/minitrace-go.svg)](https://github.com/pingcap-incubator/minitrace-go/blob/master/LICENSE)

A high-performance, ergonomic timeline tracing library for Golang.

## Basic Usage

```go
package main

import (
"fmt"
"context"
"github.com/zhongzc/minitrace-go"
"fmt"
"github.com/pingcap-incubator/minitrace-go"
)

func tracedFunc(ctx context.Context, event uint32) {
Expand Down
2 changes: 2 additions & 0 deletions buffer_list.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0.

package minitrace

import (
Expand Down
3 changes: 3 additions & 0 deletions code-of-conduct.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# PingCAP Community Code of Conduct

Please refer to our [PingCAP Community Code of Conduct](https://github.com/pingcap/community/blob/master/CODE_OF_CONDUCT.md)
3 changes: 3 additions & 0 deletions context.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0.

package minitrace

import (
Expand Down Expand Up @@ -39,6 +41,7 @@ func (s spanContext) Value(key interface{}) interface{} {
}
}

// Represents a per goroutine buffer
type localSpans struct {
spans *bufferList
createTimeNs uint64
Expand Down
2 changes: 2 additions & 0 deletions minitrace.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0.

package minitrace

type SpanSet struct {
Expand Down
2 changes: 2 additions & 0 deletions minitrace_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0.

package minitrace

import (
Expand Down
10 changes: 10 additions & 0 deletions time.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0.

package minitrace

import (
Expand All @@ -10,10 +12,18 @@ func nanotime() int64
//go:linkname walltime runtime.walltime
func walltime() (sec int64, nsec int32)

// Standard library's `time.Now()` will invoke two syscalls in Linux, one for `CLOCK_REALTIME`,
// another for `CLOCK_MONOTONIC`. In our case, we'd like to separate these two calls to measure
// time for performance purpose.
// `nanotime()` is identical to Linux's `clock_gettime(CLOCK_MONOTONIC, &ts)`
func monotimeNs() uint64 {
return uint64(nanotime())
}

// Standard library's `time.Now()` will invoke two syscalls in Linux, one for `CLOCK_REALTIME`,
// another for `CLOCK_MONOTONIC`. In our case, we'd like to separate these two calls to measure
// time for performance purpose.
// `nanotime()` is identical to Linux's `clock_gettime(CLOCK_REALTIME, &ts)`
func realtimeNs() uint64 {
sec, nsec := walltime()
return uint64(sec*1_000_000_000 + int64(nsec))
Expand Down
29 changes: 17 additions & 12 deletions trace.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Copyright 2020 TiKV Project Authors. Licensed under Apache-2.0.

package minitrace

import (
Expand Down Expand Up @@ -42,6 +44,7 @@ func NewSpanWithContext(ctx context.Context, event uint32) (context.Context, Spa

func NewSpan(ctx context.Context, event uint32) (res SpanHandle) {
if s, ok := ctx.(spanContext); ok {
// We'd like to modify the context on "stack" directly to eliminate heap memory allocation
res.spanContext = s
} else if s, ok := ctx.Value(activeTracingKey).(spanContext); ok {
res.spanContext.parent = ctx
Expand All @@ -56,43 +59,45 @@ func NewSpan(ctx context.Context, event uint32) (res SpanHandle) {
id := atomic.AddUint32(&res.spanContext.tracingContext.maxId, 1)
goid := gid.Get()

if goid == res.spanContext.currentGid {
slot := res.spanContext.tracedSpans.spans.slot()
// Use per goroutine buffer to reduce synchronization overhead.
if goid != res.spanContext.currentGid {
bl := newBufferList()
slot := bl.slot()
slot.Id = id
slot.Parent = res.spanContext.currentId
slot.BeginNs = monotimeNs()
slot.Event = event

res.spanContext.tracedSpans.refCount += 1
res.spanContext.tracedSpans = &localSpans{
spans: bl,
createTimeNs: realtimeNs(),
refCount: 1,
}
res.spanContext.currentId = id
res.spanContext.currentGid = goid
res.endNs = &slot.EndNs
return
} else {
bl := newBufferList()
slot := bl.slot()
slot := res.spanContext.tracedSpans.spans.slot()
slot.Id = id
slot.Parent = res.spanContext.currentId
slot.BeginNs = monotimeNs()
slot.Event = event

res.spanContext.tracedSpans = &localSpans{
spans: bl,
createTimeNs: realtimeNs(),
refCount: 1,
}
res.spanContext.tracedSpans.refCount += 1
res.spanContext.currentId = id
res.spanContext.currentGid = goid
res.endNs = &slot.EndNs
return
}

return
}

type SpanHandle struct {
spanContext spanContext
endNs *uint64
}

// TODO: Prevent users from calling twice
func (hd *SpanHandle) Finish() {
if hd.endNs != nil {
*hd.endNs = monotimeNs()
Expand Down

0 comments on commit a9c25a8

Please sign in to comment.