-
Notifications
You must be signed in to change notification settings - Fork 34
/
storage_tcp.go
103 lines (85 loc) · 1.69 KB
/
storage_tcp.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package tealogs
import (
"errors"
"github.com/TeaWeb/code/tealogs/accesslogs"
"github.com/iwind/TeaGo/logs"
"net"
"sync"
)
// TCP存储策略
type TCPStorage struct {
Storage `yaml:", inline"`
Network string `yaml:"network" json:"network"` // tcp, unix
Addr string `yaml:"addr" json:"addr"`
writeLocker sync.Mutex
connLocker sync.Mutex
conn net.Conn
}
// 开启
func (this *TCPStorage) Start() error {
if len(this.Network) == 0 {
return errors.New("'network' should not be nil")
}
if len(this.Addr) == 0 {
return errors.New("'addr' should not be nil")
}
return nil
}
// 写入日志
func (this *TCPStorage) Write(accessLogs []*accesslogs.AccessLog) error {
if len(accessLogs) == 0 {
return nil
}
err := this.connect()
if err != nil {
return err
}
conn := this.conn
if conn == nil {
return errors.New("connection should not be nil")
}
this.writeLocker.Lock()
defer this.writeLocker.Unlock()
for _, accessLog := range accessLogs {
data, err := this.FormatAccessLogBytes(accessLog)
if err != nil {
logs.Error(err)
continue
}
_, err = conn.Write(data)
if err != nil {
this.Close()
break
}
_, err = conn.Write([]byte("\n"))
if err != nil {
this.Close()
break
}
}
return nil
}
// 关闭
func (this *TCPStorage) Close() error {
this.connLocker.Lock()
defer this.connLocker.Unlock()
if this.conn != nil {
err := this.conn.Close()
this.conn = nil
return err
}
return nil
}
func (this *TCPStorage) connect() error {
this.connLocker.Lock()
defer this.connLocker.Unlock()
if this.conn != nil {
return nil
}
conn, err := net.Dial(this.Network, this.Addr)
if err != nil {
return err
}
this.conn = conn
return nil
}