Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"infoc.go",
"reporter.go",
],
importpath = "go-common/app/infra/canal/infoc",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//library/log:go_default_library",
"//library/net/ip:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,144 @@
package infoc
import (
"bytes"
"context"
"encoding/binary"
"encoding/json"
"net"
"strconv"
"sync"
"time"
"go-common/library/log"
)
var (
_infoc2Magic = []byte{172, 190} // NOTE: magic 0xAC0xBE
_infoc2Type = []byte{0, 0} // NOTE: type 0
_infocTimeout = 500 * time.Millisecond
)
// Config is infoc config.
type Config struct {
TaskID string
// udp or tcp
Proto string
Addr string
// reporter
ReporterAddr string
}
// Infoc infoc struct.
type Infoc struct {
c *Config
header []byte
// udp or tcp
conn net.Conn
lock sync.Mutex
// reporter
reporter *reporter
}
// New new infoc2 logger.
func New(c *Config) (i *Infoc) {
i = &Infoc{
c: c,
header: []byte(c.TaskID),
}
var err error
if i.conn, err = net.Dial(i.c.Proto, i.c.Addr); err != nil {
log.Error("infoc net dial error(%v)", err)
}
if c.ReporterAddr != "" {
i.reporter = newReporter(c.TaskID, c.ReporterAddr)
go i.reporter.reportproc()
}
return
}
// Rows the affected by binlog enent.
func (i *Infoc) Rows(rows int64) {
if i.reporter != nil {
i.reporter.receiveIncr(rows)
}
}
// Send send message.
func (i *Infoc) Send(ctx context.Context, key string, v interface{}) (err error) {
var b []byte
if b, err = json.Marshal(v); err != nil {
log.Error("json.Marshal(%v) error(%v)", v, err)
return
}
var (
res bytes.Buffer
buf bytes.Buffer
)
res.Write(_infoc2Magic)
// type and body buf, for calc length.
buf.Write(_infoc2Type)
buf.Write(i.header)
buf.WriteString(strconv.FormatInt(time.Now().UnixNano()/int64(time.Millisecond), 10))
// // append first arg
if _, err = buf.WriteString(string(b)); err != nil {
return
}
// put length
var ls [4]byte
binary.BigEndian.PutUint32(ls[:], uint32(buf.Len()))
res.Write(ls[:]) // NOTE: write length
res.Write(buf.Bytes()) // NOTEwrite type and body
// write
if err = i.write(res.Bytes()); err != nil {
log.Error("infoc write error(%v)", err)
return
}
if i.reporter != nil {
i.reporter.sendIncr(1)
}
return
}
// write write data into connection.
func (i *Infoc) write(bs []byte) (err error) {
defer func() {
if err != nil {
if i.conn != nil {
i.conn.Close()
}
i.conn = nil
}
i.lock.Unlock()
}()
i.lock.Lock()
// connection and write
if i.conn == nil {
if i.conn, err = net.DialTimeout(i.c.Proto, i.c.Addr, _infocTimeout); err != nil {
log.Error("infoc net dial error(%v)", err)
return
}
}
if i.c.Proto == "tcp" {
i.conn.SetDeadline(time.Now().Add(_infocTimeout))
}
if _, err = i.conn.Write(bs); err != nil {
log.Error("infoc net write error(%v)", err)
}
return
}
// Flush flush reporter count.
func (i *Infoc) Flush() {
if i.reporter != nil {
i.reporter.flush()
}
}
// Close close resource.
func (i *Infoc) Close() {
if i.conn != nil {
i.conn.Close()
}
}

View File

@@ -0,0 +1,84 @@
package infoc
import (
"fmt"
"net"
"sync/atomic"
"time"
"go-common/library/log"
"go-common/library/net/ip"
)
type reporter struct {
taskID string
addr string
iip string
receiveCount int64
sendCount int64
fails []string
}
func newReporter(taskID, addr string) (r *reporter) {
r = &reporter{
taskID: taskID,
addr: addr,
iip: ip.InternalIP(),
}
return
}
func (r *reporter) receiveIncr(delta int64) {
atomic.AddInt64(&r.receiveCount, delta)
}
func (r *reporter) sendIncr(delta int64) {
atomic.AddInt64(&r.sendCount, delta)
}
func (r *reporter) reportproc() {
tick := time.NewTicker(1 * time.Minute)
for {
<-tick.C
r.reporter()
}
}
func (r *reporter) flush() {
r.reporter()
}
func (r *reporter) reporter() {
const _timeout = time.Second
conn, err := net.DialTimeout("tcp", r.addr, _timeout)
if err != nil {
log.Error("infoc reporter flush dial error(%v)", err)
return
}
defer conn.Close()
conn.SetDeadline(time.Now().Add(_timeout))
var fails []string
for _, fail := range r.fails {
if _, err = conn.Write([]byte(fail)); err != nil {
log.Error("infoc reporter write fail error(%v)", err)
fails = append(fails, fail)
}
}
for _, rc := range r.record(time.Now()) {
if _, err = conn.Write([]byte(rc)); err != nil {
log.Error("infoc reporter write error(%v)", err)
fails = append(fails, rc)
}
}
r.fails = fails
}
func (r *reporter) record(now time.Time) []string {
rc := atomic.SwapInt64(&r.receiveCount, 0)
sc := atomic.SwapInt64(&r.sendCount, 0)
rcW := fmt.Sprintf("agent.receive.count\001%d\001%s\001%d\001%s\001\001", rc, r.iip, now.UnixNano()/int64(time.Millisecond), r.taskID)
scW := fmt.Sprintf("agent.send.success.count\001%d\001%s\001%d\001%s\001\001", sc, r.iip, now.UnixNano()/int64(time.Millisecond), r.taskID)
return []string{rcW, scW}
}