Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit 47fb634

Browse files
authored
Merge pull request #134 from SkyAPM/develop
New Agent
2 parents 21106e6 + ccba0cc commit 47fb634

File tree

11 files changed

+474
-259
lines changed

11 files changed

+474
-259
lines changed

docs/zh/install-sdk.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ skywalking.enable=1
5151
skywalking.version=6
5252
; app_code代码,不要含特殊字符,请使用数字、字母、下换线。(默认为:hello_skywalking)
5353
skywalking.app_code=hello_skywalking
54-
; sock文件路径(默认值为/tmp/sky_agent.sock)
55-
skywalking.sock_path=/tmp/sky_agent.sock
54+
; sock文件路径(默认值为/tmp/sky-agent.sock)
55+
skywalking.sock_path=/tmp/sky-agent.sock
5656
```
5757

5858

skywalking.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ ZEND_DECLARE_MODULE_GLOBALS(skywalking)
7070
static int le_skywalking;
7171
static int application_instance = 0;
7272
static int application_id = 0;
73+
static char application_uuid[37] = {0};
7374
static int sky_increment_id = 0;
7475
static int cli_debug = 0;
7576

@@ -85,7 +86,7 @@ PHP_INI_BEGIN()
8586
STD_PHP_INI_BOOLEAN("skywalking.enable", "0", PHP_INI_ALL, OnUpdateBool, enable, zend_skywalking_globals, skywalking_globals)
8687
STD_PHP_INI_ENTRY("skywalking.version", "6", PHP_INI_ALL, OnUpdateLong, version, zend_skywalking_globals, skywalking_globals)
8788
STD_PHP_INI_ENTRY("skywalking.app_code", "hello_skywalking", PHP_INI_ALL, OnUpdateString, app_code, zend_skywalking_globals, skywalking_globals)
88-
STD_PHP_INI_ENTRY("skywalking.sock_path", "/tmp/sky_agent.sock", PHP_INI_ALL, OnUpdateString, sock_path, zend_skywalking_globals, skywalking_globals)
89+
STD_PHP_INI_ENTRY("skywalking.sock_path", "/tmp/sky-agent.sock", PHP_INI_ALL, OnUpdateString, sock_path, zend_skywalking_globals, skywalking_globals)
8990
PHP_INI_END()
9091

9192
/* }}} */
@@ -1361,6 +1362,7 @@ static void request_init() {
13611362
generate_context();
13621363

13631364
add_assoc_long(&SKYWALKING_G(UpstreamSegment), "application_instance", application_instance);
1365+
add_assoc_stringl(&SKYWALKING_G(UpstreamSegment), "uuid", application_uuid, strlen(application_uuid));
13641366
add_assoc_long(&SKYWALKING_G(UpstreamSegment), "pid", getppid());
13651367
add_assoc_long(&SKYWALKING_G(UpstreamSegment), "application_id", application_id);
13661368
add_assoc_long(&SKYWALKING_G(UpstreamSegment), "version", SKYWALKING_G(version));
@@ -1533,9 +1535,10 @@ static int sky_register() {
15331535
p = strtok(NULL, ",");
15341536
}
15351537

1536-
if (ids[0] != NULL && ids[1] != NULL) {
1538+
if (ids[0] != NULL && ids[1] != NULL && ids[2] != NULL) {
15371539
application_id = atoi(ids[0]);
15381540
application_instance = atoi(ids[1]);
1541+
strncpy(application_uuid, ids[2], sizeof application_uuid - 1);
15391542
}
15401543
}
15411544

src/agent/cmd/main.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package main
2+
3+
import (
4+
"agent/agent/logger"
5+
"agent/agent/service"
6+
"github.com/urfave/cli"
7+
"os"
8+
)
9+
10+
var log = logger.Log
11+
12+
func main() {
13+
14+
defer func() {
15+
if err := recover(); err != nil {
16+
log.Error(err)
17+
}
18+
}()
19+
20+
app := cli.NewApp()
21+
app.Name = "sky_php_agent"
22+
app.Usage = "the skywalking trace sending agent"
23+
app.Flags = []cli.Flag{
24+
cli.StringFlag{Name: "grpc", Usage: "SkyWalking collector grpc address", Value: "127.0.0.1:11800"},
25+
cli.StringFlag{Name: "socket", Usage: "Pipeline for communicating with PHP", Value: "/tmp/sky-agent.sock"},
26+
cli.IntFlag{Name: "send-rate", Usage: "Send trace 1 second by default", Value: 1},
27+
}
28+
29+
app.Action = func(c *cli.Context) error {
30+
31+
a := service.NewAgent(c)
32+
a.Run()
33+
return nil
34+
}
35+
36+
err := app.Run(os.Args)
37+
if err != nil {
38+
log.Errorln(err)
39+
}
40+
}

src/agent/logger/log.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package logger
2+
3+
import (
4+
"github.com/sirupsen/logrus"
5+
"os"
6+
)
7+
8+
var Log *logrus.Logger
9+
10+
func init() {
11+
if Log == nil {
12+
Log = logrus.New()
13+
}
14+
Log.SetOutput(os.Stdout)
15+
Log.SetFormatter(&logrus.TextFormatter{
16+
FullTimestamp: true,
17+
TimestampFormat: "2006-01-02 15:04:05",
18+
})
19+
}

src/agent/service/agent.go

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
package service
2+
3+
import (
4+
"agent/agent/logger"
5+
"agent/agent/pb/agent"
6+
"agent/agent/pb/agent2"
7+
"agent/agent/pb/register2"
8+
"container/list"
9+
"fmt"
10+
"github.com/urfave/cli"
11+
"google.golang.org/grpc"
12+
"net"
13+
"os"
14+
"sync"
15+
"time"
16+
)
17+
18+
var log = logger.Log
19+
20+
type register struct {
21+
c net.Conn
22+
body string
23+
}
24+
25+
type grpcClient struct {
26+
segmentClientV5 agent.TraceSegmentServiceClient
27+
segmentClientV6 agent2.TraceSegmentReportServiceClient
28+
pingClient5 agent.InstanceDiscoveryServiceClient
29+
pintClient6 register2.ServiceInstancePingClient
30+
}
31+
32+
type Agent struct {
33+
flag *cli.Context
34+
grpcConn *grpc.ClientConn
35+
grpcClient grpcClient
36+
socket string
37+
socketListener net.Listener
38+
register chan *register
39+
registerCache sync.Map
40+
registerCacheLock sync.Mutex
41+
trace chan string
42+
queue *list.List
43+
}
44+
45+
func NewAgent(cli *cli.Context) *Agent {
46+
var agent = &Agent{
47+
flag: cli,
48+
socket: cli.String("socket"),
49+
register: make(chan *register),
50+
trace: make(chan string),
51+
queue: list.New(),
52+
}
53+
54+
go agent.sub()
55+
56+
return agent
57+
}
58+
59+
func (t *Agent) Run() {
60+
log.Info("hello skywalking")
61+
t.connGRPC()
62+
t.listenSocket()
63+
64+
defer func() {
65+
var err error
66+
err = t.socketListener.Close()
67+
if err != nil {
68+
log.Errorln(err)
69+
}
70+
71+
err = t.grpcConn.Close()
72+
if err != nil {
73+
log.Errorln(err)
74+
}
75+
}()
76+
}
77+
78+
func (t *Agent) connGRPC() {
79+
var err error
80+
grpcAdd := t.flag.String("grpc")
81+
t.grpcConn, err = grpc.Dial(grpcAdd, grpc.WithInsecure())
82+
if err != nil {
83+
log.Panic(err)
84+
}
85+
86+
log.Infof("connection %s...", grpcAdd)
87+
t.grpcClient.segmentClientV5 = agent.NewTraceSegmentServiceClient(t.grpcConn)
88+
t.grpcClient.segmentClientV6 = agent2.NewTraceSegmentReportServiceClient(t.grpcConn)
89+
t.grpcClient.pingClient5 = agent.NewInstanceDiscoveryServiceClient(t.grpcConn)
90+
t.grpcClient.pintClient6 = register2.NewServiceInstancePingClient(t.grpcConn)
91+
}
92+
93+
func (t *Agent) listenSocket() {
94+
var err error
95+
if err = os.RemoveAll(t.socket); err != nil {
96+
log.Panic(err)
97+
}
98+
t.socketListener, err = net.Listen("unix", t.socket)
99+
if err != nil {
100+
log.Panic(err)
101+
}
102+
103+
err = os.Chmod(t.socket, os.ModeSocket|0777)
104+
if err != nil {
105+
log.Warningln(err)
106+
}
107+
108+
for {
109+
c, err := t.socketListener.Accept()
110+
if err != nil {
111+
log.Errorln(err)
112+
break
113+
}
114+
// start a new goroutine to handle
115+
// the new connection.
116+
conn := NewConn(t, c)
117+
go conn.Handle()
118+
}
119+
}
120+
121+
func (t *Agent) sub() {
122+
heartbeatTicker := time.NewTicker(time.Second * 40)
123+
defer heartbeatTicker.Stop()
124+
traceSendTicker := time.NewTicker(time.Second * time.Duration(t.flag.Int("send-rate")))
125+
defer traceSendTicker.Stop()
126+
127+
for {
128+
select {
129+
case <-traceSendTicker.C:
130+
len := t.queue.Len()
131+
if len > 0 {
132+
var segments []*upstreamSegment
133+
for i := 0; i < len; i++ {
134+
// front top 100
135+
e := t.queue.Front()
136+
st := format(fmt.Sprintf("%v", e.Value))
137+
if st != nil {
138+
segments = append(segments, st)
139+
}
140+
t.queue.Remove(e)
141+
}
142+
go t.send(segments)
143+
}
144+
case <-heartbeatTicker.C:
145+
go t.heartbeat()
146+
case register := <-t.register:
147+
go t.doRegister(register)
148+
case trace := <-t.trace:
149+
t.queue.PushBack(trace)
150+
go t.recoverRegister(trace)
151+
}
152+
}
153+
}

src/agent/service/conn.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package service
2+
3+
import (
4+
"io"
5+
"net"
6+
"strings"
7+
)
8+
9+
type Conn struct {
10+
agent *Agent
11+
c net.Conn
12+
}
13+
14+
func NewConn(a *Agent, c net.Conn) *Conn {
15+
var conn = &Conn{
16+
agent: a,
17+
c: c,
18+
}
19+
20+
return conn
21+
}
22+
23+
func (c *Conn) Handle() {
24+
25+
defer func() {
26+
c.c.Close()
27+
}()
28+
29+
buf := make([]byte, 4096)
30+
var json string
31+
var endIndex int
32+
for {
33+
n, err := c.c.Read(buf)
34+
if err != nil {
35+
if err != io.EOF {
36+
log.Warn("conn read error:", err)
37+
}
38+
return
39+
}
40+
json += string(buf[0:n])
41+
for {
42+
endIndex = strings.IndexAny(json, "\n")
43+
if endIndex >= 0 {
44+
body := json[0:endIndex]
45+
if body[:1] == "0" {
46+
c.agent.register <- &register{
47+
c: c.c,
48+
body: body[1:],
49+
}
50+
} else if body[:1] == "1" {
51+
c.agent.trace <- body[1:]
52+
}
53+
json = json[endIndex+1:]
54+
} else {
55+
break
56+
}
57+
}
58+
}
59+
}

src/agent/service/heartbeat.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package service
2+
3+
import (
4+
"agent/agent/pb/agent"
5+
"agent/agent/pb/register2"
6+
"context"
7+
"time"
8+
)
9+
10+
func (t *Agent) heartbeat() {
11+
12+
t.registerCache.Range(func(key, value interface{}) bool {
13+
log.Infoln("heartbeat")
14+
bind := value.(registerCache)
15+
16+
if bind.Version == 5 {
17+
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
18+
defer cancel()
19+
20+
_, err := t.grpcClient.pingClient5.Heartbeat(ctx, &agent.ApplicationInstanceHeartbeat{
21+
ApplicationInstanceId: bind.InstanceId,
22+
HeartbeatTime: time.Now().UnixNano() / 1000000,
23+
})
24+
25+
if err != nil {
26+
log.Error("heartbeat:", err)
27+
} else {
28+
log.Infof("heartbeat appId %d appInsId %d", bind.AppId, bind.InstanceId)
29+
}
30+
31+
} else if bind.Version == 6 {
32+
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
33+
defer cancel()
34+
35+
_, err := t.grpcClient.pintClient6.DoPing(ctx, &register2.ServiceInstancePingPkg{
36+
ServiceInstanceId: bind.InstanceId,
37+
Time: time.Now().UnixNano() / 1000000,
38+
ServiceInstanceUUID: bind.Uuid,
39+
})
40+
if err != nil {
41+
log.Error("heartbeat:", err)
42+
} else {
43+
log.Infof("heartbeat appId %d appInsId %d", bind.AppId, bind.InstanceId)
44+
}
45+
}
46+
return true
47+
})
48+
}

0 commit comments

Comments
 (0)