Opentracing support
This commit is contained in:
parent
8394549857
commit
30ffba78e6
272 changed files with 44352 additions and 63 deletions
60
vendor/github.com/uber/jaeger-client-go/utils/http_json.go
generated
vendored
Normal file
60
vendor/github.com/uber/jaeger-client-go/utils/http_json.go
generated
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
// Copyright (c) 2016 Uber Technologies, Inc.
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// GetJSON makes an HTTP call to the specified URL and parses the returned JSON into `out`.
|
||||
func GetJSON(url string, out interface{}) error {
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ReadJSON(resp, out)
|
||||
}
|
||||
|
||||
// ReadJSON reads JSON from http.Response and parses it into `out`
|
||||
func ReadJSON(resp *http.Response, out interface{}) error {
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode >= 400 {
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return fmt.Errorf("StatusCode: %d, Body: %s", resp.StatusCode, body)
|
||||
}
|
||||
|
||||
if out == nil {
|
||||
io.Copy(ioutil.Discard, resp.Body)
|
||||
return nil
|
||||
}
|
||||
|
||||
decoder := json.NewDecoder(resp.Body)
|
||||
return decoder.Decode(out)
|
||||
}
|
90
vendor/github.com/uber/jaeger-client-go/utils/localip.go
generated
vendored
Normal file
90
vendor/github.com/uber/jaeger-client-go/utils/localip.go
generated
vendored
Normal file
|
@ -0,0 +1,90 @@
|
|||
// Copyright (c) 2016 Uber Technologies, Inc.
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
)
|
||||
|
||||
// This code is borrowed from https://github.com/uber/tchannel-go/blob/dev/localip.go
|
||||
|
||||
// scoreAddr scores how likely the given addr is to be a remote address and returns the
|
||||
// IP to use when listening. Any address which receives a negative score should not be used.
|
||||
// Scores are calculated as:
|
||||
// -1 for any unknown IP addresses.
|
||||
// +300 for IPv4 addresses
|
||||
// +100 for non-local addresses, extra +100 for "up" interaces.
|
||||
func scoreAddr(iface net.Interface, addr net.Addr) (int, net.IP) {
|
||||
var ip net.IP
|
||||
if netAddr, ok := addr.(*net.IPNet); ok {
|
||||
ip = netAddr.IP
|
||||
} else if netIP, ok := addr.(*net.IPAddr); ok {
|
||||
ip = netIP.IP
|
||||
} else {
|
||||
return -1, nil
|
||||
}
|
||||
|
||||
var score int
|
||||
if ip.To4() != nil {
|
||||
score += 300
|
||||
}
|
||||
if iface.Flags&net.FlagLoopback == 0 && !ip.IsLoopback() {
|
||||
score += 100
|
||||
if iface.Flags&net.FlagUp != 0 {
|
||||
score += 100
|
||||
}
|
||||
}
|
||||
return score, ip
|
||||
}
|
||||
|
||||
// HostIP tries to find an IP that can be used by other machines to reach this machine.
|
||||
func HostIP() (net.IP, error) {
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bestScore := -1
|
||||
var bestIP net.IP
|
||||
// Select the highest scoring IP as the best IP.
|
||||
for _, iface := range interfaces {
|
||||
addrs, err := iface.Addrs()
|
||||
if err != nil {
|
||||
// Skip this interface if there is an error.
|
||||
continue
|
||||
}
|
||||
|
||||
for _, addr := range addrs {
|
||||
score, ip := scoreAddr(iface, addr)
|
||||
if score > bestScore {
|
||||
bestScore = score
|
||||
bestIP = ip
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if bestScore == -1 {
|
||||
return nil, errors.New("no addresses to listen on")
|
||||
}
|
||||
|
||||
return bestIP, nil
|
||||
}
|
52
vendor/github.com/uber/jaeger-client-go/utils/rand.go
generated
vendored
Normal file
52
vendor/github.com/uber/jaeger-client-go/utils/rand.go
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
// Copyright (c) 2016 Uber Technologies, Inc.
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// lockedSource allows a random number generator to be used by multiple goroutines concurrently.
|
||||
// The code is very similar to math/rand.lockedSource, which is unfortunately not exposed.
|
||||
type lockedSource struct {
|
||||
mut sync.Mutex
|
||||
src rand.Source
|
||||
}
|
||||
|
||||
// NewRand returns a rand.Rand that is threadsafe.
|
||||
func NewRand(seed int64) *rand.Rand {
|
||||
return rand.New(&lockedSource{src: rand.NewSource(seed)})
|
||||
}
|
||||
|
||||
func (r *lockedSource) Int63() (n int64) {
|
||||
r.mut.Lock()
|
||||
n = r.src.Int63()
|
||||
r.mut.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
// Seed implements Seed() of Source
|
||||
func (r *lockedSource) Seed(seed int64) {
|
||||
r.mut.Lock()
|
||||
r.src.Seed(seed)
|
||||
r.mut.Unlock()
|
||||
}
|
83
vendor/github.com/uber/jaeger-client-go/utils/rate_limiter.go
generated
vendored
Normal file
83
vendor/github.com/uber/jaeger-client-go/utils/rate_limiter.go
generated
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
// Copyright (c) 2016 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RateLimiter is a filter used to check if a message that is worth itemCost units is within the rate limits.
|
||||
type RateLimiter interface {
|
||||
CheckCredit(itemCost float64) bool
|
||||
}
|
||||
|
||||
type rateLimiter struct {
|
||||
sync.Mutex
|
||||
|
||||
creditsPerSecond float64
|
||||
balance float64
|
||||
maxBalance float64
|
||||
lastTick time.Time
|
||||
|
||||
timeNow func() time.Time
|
||||
}
|
||||
|
||||
// NewRateLimiter creates a new rate limiter based on leaky bucket algorithm, formulated in terms of a
|
||||
// credits balance that is replenished every time CheckCredit() method is called (tick) by the amount proportional
|
||||
// to the time elapsed since the last tick, up to max of creditsPerSecond. A call to CheckCredit() takes a cost
|
||||
// of an item we want to pay with the balance. If the balance exceeds the cost of the item, the item is "purchased"
|
||||
// and the balance reduced, indicated by returned value of true. Otherwise the balance is unchanged and return false.
|
||||
//
|
||||
// This can be used to limit a rate of messages emitted by a service by instantiating the Rate Limiter with the
|
||||
// max number of messages a service is allowed to emit per second, and calling CheckCredit(1.0) for each message
|
||||
// to determine if the message is within the rate limit.
|
||||
//
|
||||
// It can also be used to limit the rate of traffic in bytes, by setting creditsPerSecond to desired throughput
|
||||
// as bytes/second, and calling CheckCredit() with the actual message size.
|
||||
func NewRateLimiter(creditsPerSecond, maxBalance float64) RateLimiter {
|
||||
return &rateLimiter{
|
||||
creditsPerSecond: creditsPerSecond,
|
||||
balance: maxBalance,
|
||||
maxBalance: maxBalance,
|
||||
lastTick: time.Now(),
|
||||
timeNow: time.Now}
|
||||
}
|
||||
|
||||
func (b *rateLimiter) CheckCredit(itemCost float64) bool {
|
||||
b.Lock()
|
||||
defer b.Unlock()
|
||||
// calculate how much time passed since the last tick, and update current tick
|
||||
currentTime := b.timeNow()
|
||||
elapsedTime := currentTime.Sub(b.lastTick)
|
||||
b.lastTick = currentTime
|
||||
// calculate how much credit have we accumulated since the last tick
|
||||
b.balance += elapsedTime.Seconds() * b.creditsPerSecond
|
||||
if b.balance > b.maxBalance {
|
||||
b.balance = b.maxBalance
|
||||
}
|
||||
// if we have enough credits to pay for current item, then reduce balance and allow
|
||||
if b.balance >= itemCost {
|
||||
b.balance -= itemCost
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
104
vendor/github.com/uber/jaeger-client-go/utils/udp_client.go
generated
vendored
Normal file
104
vendor/github.com/uber/jaeger-client-go/utils/udp_client.go
generated
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
// Copyright (c) 2016 Uber Technologies, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
|
||||
"github.com/apache/thrift/lib/go/thrift"
|
||||
|
||||
"github.com/uber/jaeger-client-go/thrift-gen/agent"
|
||||
"github.com/uber/jaeger-client-go/thrift-gen/jaeger"
|
||||
"github.com/uber/jaeger-client-go/thrift-gen/zipkincore"
|
||||
)
|
||||
|
||||
// UDPPacketMaxLength is the max size of UDP packet we want to send, synced with jaeger-agent
|
||||
const UDPPacketMaxLength = 65000
|
||||
|
||||
// AgentClientUDP is a UDP client to Jaeger agent that implements agent.Agent interface.
|
||||
type AgentClientUDP struct {
|
||||
agent.Agent
|
||||
io.Closer
|
||||
|
||||
connUDP *net.UDPConn
|
||||
client *agent.AgentClient
|
||||
maxPacketSize int // max size of datagram in bytes
|
||||
thriftBuffer *thrift.TMemoryBuffer // buffer used to calculate byte size of a span
|
||||
}
|
||||
|
||||
// NewAgentClientUDP creates a client that sends spans to Jaeger Agent over UDP.
|
||||
func NewAgentClientUDP(hostPort string, maxPacketSize int) (*AgentClientUDP, error) {
|
||||
if maxPacketSize == 0 {
|
||||
maxPacketSize = UDPPacketMaxLength
|
||||
}
|
||||
|
||||
thriftBuffer := thrift.NewTMemoryBufferLen(maxPacketSize)
|
||||
protocolFactory := thrift.NewTCompactProtocolFactory()
|
||||
client := agent.NewAgentClientFactory(thriftBuffer, protocolFactory)
|
||||
|
||||
destAddr, err := net.ResolveUDPAddr("udp", hostPort)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
connUDP, err := net.DialUDP(destAddr.Network(), nil, destAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := connUDP.SetWriteBuffer(maxPacketSize); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
clientUDP := &AgentClientUDP{
|
||||
connUDP: connUDP,
|
||||
client: client,
|
||||
maxPacketSize: maxPacketSize,
|
||||
thriftBuffer: thriftBuffer}
|
||||
return clientUDP, nil
|
||||
}
|
||||
|
||||
// EmitZipkinBatch implements EmitZipkinBatch() of Agent interface
|
||||
func (a *AgentClientUDP) EmitZipkinBatch(spans []*zipkincore.Span) error {
|
||||
return errors.New("Not implemented")
|
||||
}
|
||||
|
||||
// EmitBatch implements EmitBatch() of Agent interface
|
||||
func (a *AgentClientUDP) EmitBatch(batch *jaeger.Batch) error {
|
||||
a.thriftBuffer.Reset()
|
||||
a.client.SeqId = 0 // we have no need for distinct SeqIds for our one-way UDP messages
|
||||
if err := a.client.EmitBatch(batch); err != nil {
|
||||
return err
|
||||
}
|
||||
if a.thriftBuffer.Len() > a.maxPacketSize {
|
||||
return fmt.Errorf("Data does not fit within one UDP packet; size %d, max %d, spans %d",
|
||||
a.thriftBuffer.Len(), a.maxPacketSize, len(batch.Spans))
|
||||
}
|
||||
_, err := a.connUDP.Write(a.thriftBuffer.Bytes())
|
||||
return err
|
||||
}
|
||||
|
||||
// Close implements Close() of io.Closer and closes the underlying UDP connection.
|
||||
func (a *AgentClientUDP) Close() error {
|
||||
return a.connUDP.Close()
|
||||
}
|
93
vendor/github.com/uber/jaeger-client-go/utils/utils.go
generated
vendored
Normal file
93
vendor/github.com/uber/jaeger-client-go/utils/utils.go
generated
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
// Copyright (c) 2016 Uber Technologies, Inc.
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrEmptyIP an error for empty ip strings
|
||||
ErrEmptyIP = errors.New("empty string given for ip")
|
||||
|
||||
// ErrNotHostColonPort an error for invalid host port string
|
||||
ErrNotHostColonPort = errors.New("expecting host:port")
|
||||
|
||||
// ErrNotFourOctets an error for the wrong number of octets after splitting a string
|
||||
ErrNotFourOctets = errors.New("Wrong number of octets")
|
||||
)
|
||||
|
||||
// ParseIPToUint32 converts a string ip (e.g. "x.y.z.w") to an uint32
|
||||
func ParseIPToUint32(ip string) (uint32, error) {
|
||||
if ip == "" {
|
||||
return 0, ErrEmptyIP
|
||||
}
|
||||
|
||||
if ip == "localhost" {
|
||||
return 127<<24 | 1, nil
|
||||
}
|
||||
|
||||
octets := strings.Split(ip, ".")
|
||||
if len(octets) != 4 {
|
||||
return 0, ErrNotFourOctets
|
||||
}
|
||||
|
||||
var intIP uint32
|
||||
for i := 0; i < 4; i++ {
|
||||
octet, err := strconv.Atoi(octets[i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
intIP = (intIP << 8) | uint32(octet)
|
||||
}
|
||||
|
||||
return intIP, nil
|
||||
}
|
||||
|
||||
// ParsePort converts port number from string to uin16
|
||||
func ParsePort(portString string) (uint16, error) {
|
||||
port, err := strconv.ParseUint(portString, 10, 16)
|
||||
return uint16(port), err
|
||||
}
|
||||
|
||||
// PackIPAsUint32 packs an IPv4 as uint32
|
||||
func PackIPAsUint32(ip net.IP) uint32 {
|
||||
if ipv4 := ip.To4(); ipv4 != nil {
|
||||
return binary.BigEndian.Uint32(ipv4)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// TimeToMicrosecondsSinceEpochInt64 converts Go time.Time to a long
|
||||
// representing time since epoch in microseconds, which is used expected
|
||||
// in the Jaeger spans encoded as Thrift.
|
||||
func TimeToMicrosecondsSinceEpochInt64(t time.Time) int64 {
|
||||
// ^^^ Passing time.Time by value is faster than passing a pointer!
|
||||
// BenchmarkTimeByValue-8 2000000000 1.37 ns/op
|
||||
// BenchmarkTimeByPtr-8 2000000000 1.98 ns/op
|
||||
|
||||
return t.UnixNano() / 1000
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue