30 Commits

Author SHA1 Message Date
1858dfa102 update README 2016-04-16 19:12:44 +12:00
89b67f8559 nmdc-log-service: track sample systemd unit 2016-04-16 19:01:20 +12:00
649b3dfcab libnmdc: patch panic on read() returning an error (interface type) that can't be cast to net.error 2016-04-16 18:27:14 +12:00
ed64887ddc nmdc-log-service: prevent logging the same connection-state message repeatedly 2016-04-16 18:21:38 +12:00
2113139cdc scripts: strip sensitive gopath string out of release binaries 2016-04-16 18:18:09 +12:00
07441628d9 nmdc-log-service: use NewUserInfo helper to set passive/1-connected in tag 2016-04-10 16:37:21 +12:00
34dd9d515c Added tag nmdc-log-service-1.0.3 for changeset 4116422bb102 2016-04-04 19:04:32 +12:00
32f64690c9 update README 2016-04-04 19:04:27 +12:00
3f66cd93c7 Added tag libnmdc-r5 for changeset 75a78f6a78f2 2016-04-04 19:02:56 +12:00
9b32682c8a libnmdc: support hub-redirects 2016-04-04 19:01:55 +12:00
c9e95df0df libnmdc: fix for previous 2016-04-04 19:01:47 +12:00
a2b94e8724 libnmdc: send protocol-level keepalives 2016-04-04 18:57:50 +12:00
3dfef302ee Added tag nmdc-log-service-1.0.2 for changeset da9f123633f9 2016-04-03 19:24:12 +12:00
611a934a4e nmdc-log-service: readme 2016-04-03 19:24:03 +12:00
1a3617b960 libnmdc: readme 2016-04-03 19:23:14 +12:00
a37b1773d0 Added tag libnmdc-r4 for changeset 050b424a7c5d 2016-04-03 19:22:02 +12:00
09301f138c libnmdc: (comment) 2016-04-03 19:21:32 +12:00
8d7b0b46af libnmdc: fix bugs with buffer splitting 2016-04-03 19:20:58 +12:00
73f6d66cbd libnmdc: reinstate backward-compatibility re new sync api 2016-04-03 18:59:11 +12:00
019f67a7de libnmdc: ensure we always flush protocol commands that happened alongside a disconnection event 2016-04-03 18:54:56 +12:00
debc14cea3 libnmdc: isolate constants 2016-04-03 18:53:14 +12:00
ba378a8245 libnmdc: optional synchronous-based API instead of channel-based API 2016-04-03 18:52:19 +12:00
e3a92da5f6 libnmdc: remove redundant bool=false initialisation (handled in $Lock callback) 2016-04-03 18:38:43 +12:00
99e4ebb842 libnmdc: set our own state before emitting statechange event 2016-04-03 18:38:06 +12:00
4499c7306d libnmdc: clear fullbuffer prior to connection attempt 2016-04-03 18:36:46 +12:00
d391159abe libnmdc: avoid meaningless cast 2016-04-03 18:35:11 +12:00
e111c99886 libnmdc: assert state parameter is set correctly 2016-04-03 18:35:05 +12:00
393f156b0e Added tag nmdc-log-service-1.0.1 for changeset fca41372e400 2016-04-03 13:36:47 +12:00
7cd49c2c8a update README files 2016-04-03 13:36:41 +12:00
163b6623f8 Added tag libnmdc-r3 for changeset d8b64d5527c2 2016-04-03 13:33:48 +12:00
7 changed files with 195 additions and 57 deletions

View File

@@ -1,3 +1,9 @@
945ab4b16d05aa084f71bf5da9a3f687e0ec8bbd libnmdc-r1 945ab4b16d05aa084f71bf5da9a3f687e0ec8bbd libnmdc-r1
02a360e95480b97ddad83add5db48b2766339a99 nmdc-log-service-1.0.0 02a360e95480b97ddad83add5db48b2766339a99 nmdc-log-service-1.0.0
137c1b65039e03c80379826a6efdfd808f6fbc8f libnmdc-r2 137c1b65039e03c80379826a6efdfd808f6fbc8f libnmdc-r2
d8b64d5527c2a5e4d76872e5bc3d69f7646135c6 libnmdc-r3
fca41372e400853775b02e951f9db91d87f41adb nmdc-log-service-1.0.1
050b424a7c5d5a27c9323c8810f3afbead1f5b96 libnmdc-r4
da9f123633f9c28be6435ed7898139665d4c39d9 nmdc-log-service-1.0.2
75a78f6a78f249a2cd8aa3d29f7e5e6319b4e03b libnmdc-r5
4116422bb10229d887f9296970a166fa1ef8c5fd nmdc-log-service-1.0.3

View File

@@ -1,7 +1,7 @@
An NMDC client protocol library for Golang. An NMDC client protocol library for Golang.
- Channel-based API. - Offers both channel-based and synchronous APIs.
- Includes a sample logging client. - Includes a sample logging client using the channel-based API.
- This code hosting site isn't (yet) compatible with `go get`. - This code hosting site isn't (yet) compatible with `go get`.
Written in golang Written in golang
@@ -9,6 +9,22 @@ Tags: nmdc
=CHANGELOG= =CHANGELOG=
2016-04-16 r6
- Fix an issue with calling `panic()` on certain types of abnormal network failure
2016-04-04 r5
- Enhancement: Support protocol keepalives
- Enhancement: Support hub redirects (`$ForceMove`)
2016-04-03 r4
- Feature: Add synchronous API
- Fix an issue with reading HubConnection's state parameter
- Fix an issue with buffered protocol commands
2016-04-03 r3
- Feature: Add `SkipVerifyTLS` option
- Fix an issue with calling `panic()` if connection failed
2016-04-02 r2 2016-04-02 r2
- Enhancement: Support NMDC-over-TLS (NMDCS) - Enhancement: Support NMDC-over-TLS (NMDCS)
- Fix an issue recieving private messages - Fix an issue recieving private messages

View File

@@ -12,6 +12,12 @@ import (
"time" "time"
) )
const (
DEFAULT_CLIENT_TAG string = "libnmdc.go"
DEFAULT_HUB_NAME string = "(unknown)"
SEND_KEEPALIVE_EVERY time.Duration = 29 * time.Second
)
type ConnectionState int type ConnectionState int
type HubEventType int type HubEventType int
@@ -69,17 +75,22 @@ var rx_incomingTo *regexp.Regexp
var ErrNotConnected error = errors.New("Not connected") var ErrNotConnected error = errors.New("Not connected")
func init() { func init() {
rx_protocolMessage = regexp.MustCompile("(?ms)^[^|]*|") rx_protocolMessage = regexp.MustCompile("(?ms)^[^|]*\\|")
rx_publicChat = regexp.MustCompile("(?ms)^<([^>]*)> (.*)$") rx_publicChat = regexp.MustCompile("(?ms)^<([^>]*)> (.*)$")
rx_incomingTo = regexp.MustCompile("(?ms)^([^ ]+) From: ([^ ]+) \\$<([^>]*)> (.*)") rx_incomingTo = regexp.MustCompile("(?ms)^([^ ]+) From: ([^ ]+) \\$<([^>]*)> (.*)")
} }
type HubConnectionOptions struct { type HubConnectionOptions struct {
Address HubAddress Address HubAddress
SkipVerifyTLS bool // using a negative verb, because bools default to false SkipVerifyTLS bool // using a negative verb, because bools default to false
Self UserInfo Self UserInfo
NickPassword string NickPassword string
// Returning messages in async mode
NumEventsToBuffer uint NumEventsToBuffer uint
// Returning messages in sync mode
OnEventSync func(HubEvent)
} }
type HubConnection struct { type HubConnection struct {
@@ -92,7 +103,8 @@ type HubConnection struct {
Users map[string]UserInfo Users map[string]UserInfo
// Streamed events // Streamed events
OnEvent chan HubEvent processEvent func(HubEvent)
OnEvent chan HubEvent
// Private state // Private state
conn net.Conn // this is an interface conn net.Conn // this is an interface
@@ -148,7 +160,7 @@ func (this *HubConnection) userJoined_NameOnly(nick string) {
_, already_existed := this.Users[nick] _, already_existed := this.Users[nick]
if !already_existed { if !already_existed {
this.Users[nick] = *NewUserInfo(nick) this.Users[nick] = *NewUserInfo(nick)
this.OnEvent <- HubEvent{EventType: EVENT_USER_JOINED, Nick: nick} this.processEvent(HubEvent{EventType: EVENT_USER_JOINED, Nick: nick})
} }
} }
@@ -156,7 +168,7 @@ func (this *HubConnection) userJoined_Full(uinf *UserInfo) {
_, already_existed := this.Users[uinf.Nick] _, already_existed := this.Users[uinf.Nick]
if !already_existed { if !already_existed {
this.Users[uinf.Nick] = *uinf this.Users[uinf.Nick] = *uinf
this.OnEvent <- HubEvent{EventType: EVENT_USER_JOINED, Nick: uinf.Nick} this.processEvent(HubEvent{EventType: EVENT_USER_JOINED, Nick: uinf.Nick})
} }
} }
@@ -205,14 +217,14 @@ func (this *HubConnection) processProtocolMessage(message string) {
// ``````````` // ```````````
if rx_publicChat.MatchString(message) { if rx_publicChat.MatchString(message) {
pubchat_parts := rx_publicChat.FindStringSubmatch(message) pubchat_parts := rx_publicChat.FindStringSubmatch(message)
this.OnEvent <- HubEvent{EventType: EVENT_PUBLIC, Nick: pubchat_parts[1], Message: NMDCUnescape(pubchat_parts[2])} this.processEvent(HubEvent{EventType: EVENT_PUBLIC, Nick: pubchat_parts[1], Message: NMDCUnescape(pubchat_parts[2])})
return return
} }
// System messages // System messages
// ``````````````` // ```````````````
if message[0] != '$' { if message[0] != '$' {
this.OnEvent <- HubEvent{EventType: EVENT_SYSTEM_MESSAGE_FROM_HUB, Nick: this.HubName, Message: NMDCUnescape(message)} this.processEvent(HubEvent{EventType: EVENT_SYSTEM_MESSAGE_FROM_HUB, Nick: this.HubName, Message: NMDCUnescape(message)})
return return
} }
@@ -242,27 +254,27 @@ func (this *HubConnection) processProtocolMessage(message string) {
case "$HubName": case "$HubName":
this.HubName = commandParts[1] this.HubName = commandParts[1]
this.OnEvent <- HubEvent{EventType: EVENT_HUBNAME_CHANGED, Nick: commandParts[1]} this.processEvent(HubEvent{EventType: EVENT_HUBNAME_CHANGED, Nick: commandParts[1]})
case "$ValidateDenide": // sic case "$ValidateDenide": // sic
if len(this.Hco.NickPassword) > 0 { if len(this.Hco.NickPassword) > 0 {
this.OnEvent <- HubEvent{EventType: EVENT_SYSTEM_MESSAGE_FROM_CONN, Message: "Incorrect password."} this.processEvent(HubEvent{EventType: EVENT_SYSTEM_MESSAGE_FROM_CONN, Message: "Incorrect password."})
} else { } else {
this.OnEvent <- HubEvent{EventType: EVENT_SYSTEM_MESSAGE_FROM_CONN, Message: "Nick already in use."} this.processEvent(HubEvent{EventType: EVENT_SYSTEM_MESSAGE_FROM_CONN, Message: "Nick already in use."})
} }
case "$HubIsFull": case "$HubIsFull":
this.OnEvent <- HubEvent{EventType: EVENT_SYSTEM_MESSAGE_FROM_CONN, Message: "Hub is full."} this.processEvent(HubEvent{EventType: EVENT_SYSTEM_MESSAGE_FROM_CONN, Message: "Hub is full."})
case "$BadPass": case "$BadPass":
this.OnEvent <- HubEvent{EventType: EVENT_SYSTEM_MESSAGE_FROM_CONN, Message: "Incorrect password."} this.processEvent(HubEvent{EventType: EVENT_SYSTEM_MESSAGE_FROM_CONN, Message: "Incorrect password."})
case "$GetPass": case "$GetPass":
this.SayRaw("$MyPass " + NMDCEscape(this.Hco.NickPassword) + "|") this.SayRaw("$MyPass " + NMDCEscape(this.Hco.NickPassword) + "|")
case "$Quit": case "$Quit":
delete(this.Users, commandParts[1]) delete(this.Users, commandParts[1])
this.OnEvent <- HubEvent{EventType: EVENT_USER_PART, Nick: commandParts[1]} this.processEvent(HubEvent{EventType: EVENT_USER_PART, Nick: commandParts[1]})
case "$MyINFO": case "$MyINFO":
u := UserInfo{} u := UserInfo{}
@@ -270,7 +282,7 @@ func (this *HubConnection) processProtocolMessage(message string) {
if err == nil { if err == nil {
this.userJoined_Full(&u) this.userJoined_Full(&u)
} else { } else {
this.OnEvent <- HubEvent{EventType: EVENT_DEBUG_MESSAGE, Message: err.Error()} this.processEvent(HubEvent{EventType: EVENT_DEBUG_MESSAGE, Message: err.Error()})
} }
case "$NickList": case "$NickList":
@@ -286,31 +298,30 @@ func (this *HubConnection) processProtocolMessage(message string) {
if rx_incomingTo.MatchString(commandParts[1]) { if rx_incomingTo.MatchString(commandParts[1]) {
txparts := rx_incomingTo.FindStringSubmatch(commandParts[1]) txparts := rx_incomingTo.FindStringSubmatch(commandParts[1])
if txparts[1] == this.Hco.Self.Nick && txparts[2] == txparts[3] { if txparts[1] == this.Hco.Self.Nick && txparts[2] == txparts[3] {
this.OnEvent <- HubEvent{EventType: EVENT_PRIVATE, Nick: txparts[2], Message: txparts[4]} this.processEvent(HubEvent{EventType: EVENT_PRIVATE, Nick: txparts[2], Message: txparts[4]})
valid = true valid = true
} }
} }
if !valid { if !valid {
this.OnEvent <- HubEvent{EventType: EVENT_DEBUG_MESSAGE, Message: "Malformed private message '" + commandParts[1] + "'"} this.processEvent(HubEvent{EventType: EVENT_DEBUG_MESSAGE, Message: "Malformed private message '" + commandParts[1] + "'"})
} }
case "$UserIP": case "$UserIP":
// Final message in PtokaX connection handshake - trigger connection callback. // Final message in PtokaX connection handshake - trigger connection callback.
// This might not be the case for other hubsofts, though // This might not be the case for other hubsofts, though
if this.State != CONNECTIONSTATE_CONNECTED { if this.State != CONNECTIONSTATE_CONNECTED {
this.OnEvent <- HubEvent{EventType: EVENT_CONNECTION_STATE_CHANGED, StateChange: CONNECTIONSTATE_CONNECTED} this.processEvent(HubEvent{EventType: EVENT_CONNECTION_STATE_CHANGED, StateChange: CONNECTIONSTATE_CONNECTED})
this.State = CONNECTIONSTATE_CONNECTED this.State = CONNECTIONSTATE_CONNECTED
} }
case "$UserCommand":
// TODO
case "$ForceMove": case "$ForceMove":
// TODO this.Hco.Address = HubAddress(commandParts[1])
this.conn.Close() // we'll reconnect onto the new address
// IGNORABLE COMMANDS // IGNORABLE COMMANDS
case "$Supports": case "$Supports":
case "$UserCommand": // TODO $UserCommand 1 1 Group chat\New group chat$<%[mynick]> !groupchat_new&#124;|
case "$UserList": case "$UserList":
case "$OpList": case "$OpList":
case "$HubTopic": case "$HubTopic":
@@ -318,11 +329,25 @@ func (this *HubConnection) processProtocolMessage(message string) {
case "$ConnectToMe": case "$ConnectToMe":
default: default:
this.OnEvent <- HubEvent{EventType: EVENT_DEBUG_MESSAGE, Message: "Unhandled protocol command '" + commandParts[0] + "'"} this.processEvent(HubEvent{EventType: EVENT_DEBUG_MESSAGE, Message: "Unhandled protocol command '" + commandParts[0] + "'"})
} }
} }
func CheckIsNetTimeout(err error) bool {
if err == nil {
return false
}
switch err.(type) {
case net.Error:
return err.(net.Error).Timeout()
default:
return false
}
}
func (this *HubConnection) worker() { func (this *HubConnection) worker() {
var fullBuffer string var fullBuffer string
var err error = nil var err error = nil
@@ -333,6 +358,8 @@ func (this *HubConnection) worker() {
// If we're not connected, attempt reconnect // If we're not connected, attempt reconnect
if this.conn == nil { if this.conn == nil {
fullBuffer = "" // clear
if this.Hco.Address.IsSecure() { if this.Hco.Address.IsSecure() {
this.conn, err = tls.Dial("tcp", this.Hco.Address.GetHostOnly(), &tls.Config{ this.conn, err = tls.Dial("tcp", this.Hco.Address.GetHostOnly(), &tls.Config{
InsecureSkipVerify: this.Hco.SkipVerifyTLS, InsecureSkipVerify: this.Hco.SkipVerifyTLS,
@@ -342,30 +369,36 @@ func (this *HubConnection) worker() {
} }
if err != nil { if err != nil {
this.OnEvent <- HubEvent{EventType: EVENT_CONNECTION_STATE_CHANGED, StateChange: CONNECTIONSTATE_CONNECTING} this.State = CONNECTIONSTATE_DISCONNECTED
this.connValid = false this.connValid = false
} else { } else {
this.State = CONNECTIONSTATE_CONNECTING
this.connValid = true this.connValid = true
this.processEvent(HubEvent{EventType: EVENT_CONNECTION_STATE_CHANGED, StateChange: CONNECTIONSTATE_CONNECTING})
} }
} }
// Read from socket into our local buffer (blocking) // Read from socket into our local buffer (blocking)
if this.connValid { if this.connValid {
readBuff := make([]byte, 4096) readBuff := make([]byte, 1024)
this.conn.SetReadDeadline(time.Now().Add(SEND_KEEPALIVE_EVERY))
nbytes, err = this.conn.Read(readBuff) nbytes, err = this.conn.Read(readBuff)
if CheckIsNetTimeout(err) {
// No data before read deadline
err = nil
// Send KA packet
_, err = this.conn.Write([]byte("|"))
}
if nbytes > 0 { if nbytes > 0 {
fullBuffer += string(readBuff[0:nbytes]) fullBuffer += string(readBuff[0:nbytes])
} }
} }
// Maybe we disconnected
if err != nil {
this.OnEvent <- HubEvent{EventType: EVENT_CONNECTION_STATE_CHANGED, StateChange: CONNECTIONSTATE_DISCONNECTED, Message: err.Error()}
this.conn = nil
time.Sleep(30 * time.Second) // Wait before reconnect
continue
}
// Attempt to parse a message block // Attempt to parse a message block
for len(fullBuffer) > 0 { for len(fullBuffer) > 0 {
for len(fullBuffer) > 0 && fullBuffer[0] == '|' { for len(fullBuffer) > 0 && fullBuffer[0] == '|' {
@@ -373,38 +406,66 @@ func (this *HubConnection) worker() {
} }
protocolMessage := rx_protocolMessage.FindString(fullBuffer) protocolMessage := rx_protocolMessage.FindString(fullBuffer)
if len(protocolMessage) > 0 { if len(protocolMessage) > 0 {
this.processProtocolMessage(string(protocolMessage)) this.processProtocolMessage(protocolMessage[:len(protocolMessage)-1])
fullBuffer = fullBuffer[len(protocolMessage):] fullBuffer = fullBuffer[len(protocolMessage):]
} else { } else {
break break
} }
} }
// Maybe we disconnected
// Perform this check *last*, to ensure we've had a final shot at
// clearing out any queued messages
if err != nil {
this.State = CONNECTIONSTATE_DISCONNECTED
this.conn = nil
this.connValid = false
this.processEvent(HubEvent{EventType: EVENT_CONNECTION_STATE_CHANGED, StateChange: CONNECTIONSTATE_DISCONNECTED, Message: err.Error()})
time.Sleep(30 * time.Second) // Wait before reconnect
continue
}
} }
} }
func (this *HubConnectionOptions) prepareConnection() *HubConnection {
if this.Self.ClientTag == "" {
this.Self.ClientTag = DEFAULT_CLIENT_TAG
}
hc := HubConnection{
Hco: this,
HubName: DEFAULT_HUB_NAME,
State: CONNECTIONSTATE_DISCONNECTED,
Users: make(map[string]UserInfo),
}
return &hc
}
// Connects to an NMDC server, and spawns a background goroutine to handle // Connects to an NMDC server, and spawns a background goroutine to handle
// protocol messages. Client code should select on all the interface channels. // protocol messages. Client code should select on all the interface channels.
func (this *HubConnectionOptions) Connect() *HubConnection { func (this *HubConnectionOptions) Connect() *HubConnection {
if this.Self.ClientTag == "" {
this.Self.ClientTag = "libnmdc.go"
}
if this.NumEventsToBuffer < 1 { if this.NumEventsToBuffer < 1 {
this.NumEventsToBuffer = 1 this.NumEventsToBuffer = 1
} }
hc := HubConnection{ hc := this.prepareConnection()
Hco: this, hc.OnEvent = make(chan HubEvent, this.NumEventsToBuffer)
HubName: "(unknown)", hc.processEvent = func(ev HubEvent) {
State: CONNECTIONSTATE_DISCONNECTED, hc.OnEvent <- ev
Users: make(map[string]UserInfo),
OnEvent: make(chan HubEvent, this.NumEventsToBuffer),
sentOurHello: false,
} }
go hc.worker() go hc.worker()
return hc
return &hc }
// Connects to an NMDC server, and blocks forever to handle protocol messages.
// Client code should supply an event handling function.
func (this *HubConnectionOptions) ConnectSync() {
hc := this.prepareConnection()
hc.worker()
} }

View File

@@ -23,9 +23,30 @@ Usage of nmdc-log-service:
-Password string -Password string
Registered nick password Registered nick password
-Server string -Server string
Addresses to connect to (comma-separated)` Addresses to connect to (comma-separated)
-VerifyTLS
Verify TLS certificates (default true)
`
=CHANGELOG= =CHANGELOG=
2016-04-16 1.0.4
- Enhancement: Upgrade `libnmdc` from `r5` to `r6`
- Include a sample systemd unit script in source archive
- Fix an issue showing zero connected hubs in user tag
- Fix a cosmetic issue with logging repeated identical connection failure messages
2016-04-04 1.0.3
- Enhancement: Upgrade `libnmdc` from `r4` to `r5`
2016-04-03 1.0.2
- Enhancement: Upgrade `libnmdc` from `r3` to `r4`
2016-04-03 1.0.1
- Enhancement: Add `-VerifyTLS` option
- Enhancement: Upgrade `libnmdc` from `r2` to `r3`
- Fix an issue writing log files on Linux
- Fix a cosmetic issue with error message formatting
2016-04-02 1.0.0 2016-04-02 1.0.0
- Initial public release - Initial public release

View File

@@ -7,6 +7,12 @@ export GOPATH=$(
cygpath -w "$(pwd)" cygpath -w "$(pwd)"
) )
sanitise() {
local tmp=$(mktemp)
cat "$1" | perl -pe 's~C:.Users.......Documents.DEV.~C:/xxxxxxxxxxxxxxxxxxxxxxxxx/~g' > "$tmp"
mv "$tmp" "$1"
}
main() { main() {
local version="" local version=""
@@ -25,21 +31,25 @@ main() {
echo "Building win64..." echo "Building win64..."
GOARCH=amd64 GOOS=windows go build -a -ldflags -s -o nmdc-log-service.exe GOARCH=amd64 GOOS=windows go build -a -ldflags -s -o nmdc-log-service.exe
sanitise nmdc-log-service.exe
7z a -mx9 nmdc-log-service-${version}-win64.7z nmdc-log-service.exe >/dev/null 7z a -mx9 nmdc-log-service-${version}-win64.7z nmdc-log-service.exe >/dev/null
rm ./nmdc-log-service.exe rm ./nmdc-log-service.exe
echo "Building win32..." echo "Building win32..."
GOARCH=386 GOOS=windows go build -a -ldflags -s -o nmdc-log-service.exe GOARCH=386 GOOS=windows go build -a -ldflags -s -o nmdc-log-service.exe
sanitise nmdc-log-service.exe
7z a -mx9 nmdc-log-service-${version}-win32.7z nmdc-log-service.exe >/dev/null 7z a -mx9 nmdc-log-service-${version}-win32.7z nmdc-log-service.exe >/dev/null
rm ./nmdc-log-service.exe rm ./nmdc-log-service.exe
echo "Building linux64..." echo "Building linux64..."
GOARCH=amd64 GOOS=linux go build -a -ldflags -s -o nmdc-log-service GOARCH=amd64 GOOS=linux go build -a -ldflags -s -o nmdc-log-service
sanitise nmdc-log-service
XZ_OPT=-9 tar caf nmdc-log-service-${version}-linux64.tar.xz nmdc-log-service --owner=0 --group=0 XZ_OPT=-9 tar caf nmdc-log-service-${version}-linux64.tar.xz nmdc-log-service --owner=0 --group=0
rm ./nmdc-log-service rm ./nmdc-log-service
echo "Building linux32..." echo "Building linux32..."
GOARCH=386 GOOS=linux go build -a -ldflags -s -o nmdc-log-service GOARCH=386 GOOS=linux go build -a -ldflags -s -o nmdc-log-service
sanitise nmdc-log-service
XZ_OPT=-9 tar caf nmdc-log-service-${version}-linux32.tar.xz nmdc-log-service --owner=0 --group=0 XZ_OPT=-9 tar caf nmdc-log-service-${version}-linux32.tar.xz nmdc-log-service --owner=0 --group=0
rm ./nmdc-log-service rm ./nmdc-log-service

View File

@@ -0,0 +1,14 @@
[Unit]
Description=NMDC Log Service
[Service]
Environment=TZ=Etc/UTC
Type=simple
ExecStart=/home/hublog/nmdc-log-service -Dir /home/hublog/logs/ -Server ... -Nick ... -Password '...' -VerifyTLS=false
Restart=always
RestartSec=30s
User=hublog
Group=nogroup
[Install]
WantedBy=multi-user.target

View File

@@ -51,12 +51,16 @@ func LogMessage(hub, message string) {
} }
} }
func HubWorker(addr, nick, password string) { type HubWorker struct {
LastConnectionStateMessage string
}
func (this *HubWorker) MainLoop(addr, nick, password string) {
opts := libnmdc.HubConnectionOptions{ opts := libnmdc.HubConnectionOptions{
Address: libnmdc.HubAddress(addr), Address: libnmdc.HubAddress(addr),
SkipVerifyTLS: !VerifyTLS, SkipVerifyTLS: !VerifyTLS,
Self: libnmdc.UserInfo{Nick: nick}, Self: *libnmdc.NewUserInfo(nick),
NickPassword: password, NickPassword: password,
} }
hub := opts.Connect() hub := opts.Connect()
@@ -71,11 +75,16 @@ func HubWorker(addr, nick, password string) {
switch event.EventType { switch event.EventType {
case libnmdc.EVENT_CONNECTION_STATE_CHANGED: case libnmdc.EVENT_CONNECTION_STATE_CHANGED:
if LogConnectionState { if LogConnectionState {
str := "* " + event.StateChange.Format()
if len(event.Message) > 0 { if len(event.Message) > 0 {
LogMessage(addr, "* "+event.StateChange.Format()+" ("+event.Message+")") str += " (" + event.Message + ")"
} else {
LogMessage(addr, "* "+event.StateChange.Format())
} }
// Prevent logging the same message repeatedly
if str != this.LastConnectionStateMessage {
LogMessage(addr, str)
}
this.LastConnectionStateMessage = str
} }
case libnmdc.EVENT_PUBLIC: case libnmdc.EVENT_PUBLIC:
@@ -135,7 +144,8 @@ func main() {
os.MkdirAll(GetDirectoryNameForHub(hubaddr), 0755) os.MkdirAll(GetDirectoryNameForHub(hubaddr), 0755)
// Launch logger // Launch logger
go HubWorker(hubaddr, *nick, *password) hw := HubWorker{}
go hw.MainLoop(hubaddr, *nick, *password)
launch_ct++ launch_ct++
} }