diff options
Diffstat (limited to 'matterclient/matterclient.go')
-rw-r--r-- | matterclient/matterclient.go | 88 |
1 files changed, 62 insertions, 26 deletions
diff --git a/matterclient/matterclient.go b/matterclient/matterclient.go index 07994c61..18006c7a 100644 --- a/matterclient/matterclient.go +++ b/matterclient/matterclient.go @@ -8,7 +8,7 @@ import ( "time" "github.com/gorilla/websocket" - "github.com/hashicorp/golang-lru" + lru "github.com/hashicorp/golang-lru" "github.com/jpillora/backoff" prefixed "github.com/matterbridge/logrus-prefixed-formatter" "github.com/mattermost/mattermost-server/model" @@ -49,13 +49,13 @@ type Team struct { type MMClient struct { sync.RWMutex *Credentials + Team *Team OtherTeams []*Team Client *model.Client4 User *model.User Users map[string]*model.User MessageChan chan *Message - log *logrus.Entry WsClient *websocket.Conn WsQuit bool WsAway bool @@ -64,31 +64,61 @@ type MMClient struct { WsPingChan chan *model.WebSocketResponse ServerVersion string OnWsConnect func() - lruCache *lru.Cache + + logger *logrus.Entry + rootLogger *logrus.Logger + lruCache *lru.Cache } -func New(login, pass, team, server string) *MMClient { - cred := &Credentials{Login: login, Pass: pass, Team: team, Server: server} - mmclient := &MMClient{Credentials: cred, MessageChan: make(chan *Message, 100), Users: make(map[string]*model.User)} - logrus.SetFormatter(&prefixed.TextFormatter{PrefixPadding: 13, DisableColors: true}) - mmclient.log = logrus.WithFields(logrus.Fields{"prefix": "matterclient"}) - mmclient.lruCache, _ = lru.New(500) - return mmclient +// New will instantiate a new Matterclient with the specified login details without connecting. +func New(login string, pass string, team string, server string) *MMClient { + rootLogger := logrus.New() + rootLogger.SetFormatter(&prefixed.TextFormatter{ + PrefixPadding: 13, + DisableColors: true, + }) + + cred := &Credentials{ + Login: login, + Pass: pass, + Team: team, + Server: server, + } + + cache, _ := lru.New(500) + return &MMClient{ + Credentials: cred, + MessageChan: make(chan *Message, 100), + Users: make(map[string]*model.User), + rootLogger: rootLogger, + lruCache: cache, + logger: rootLogger.WithFields(logrus.Fields{"prefix": "matterclient"}), + } } +// SetDebugLog activates debugging logging on all Matterclient log output. func (m *MMClient) SetDebugLog() { - logrus.SetFormatter(&prefixed.TextFormatter{PrefixPadding: 13, DisableColors: true, FullTimestamp: false, ForceFormatting: true}) + m.rootLogger.SetFormatter(&prefixed.TextFormatter{ + PrefixPadding: 13, + DisableColors: true, + FullTimestamp: false, + ForceFormatting: true, + }) } +// SetLogLevel tries to parse the specified level and if successful sets +// the log level accordingly. Accepted levels are: 'debug', 'info', 'warn', +// 'error', 'fatal' and 'panic'. func (m *MMClient) SetLogLevel(level string) { l, err := logrus.ParseLevel(level) if err != nil { - logrus.SetLevel(logrus.InfoLevel) - return + m.logger.Warnf("Failed to parse specified log-level '%s': %#v", level, err) + } else { + m.rootLogger.SetLevel(l) } - logrus.SetLevel(l) } +// Login tries to connect the client with the loging details with which it was initialized. func (m *MMClient) Login() error { // check if this is a first connect or a reconnection firstConnection := true @@ -131,13 +161,14 @@ func (m *MMClient) Login() error { return nil } +// Logout disconnects the client from the chat server. func (m *MMClient) Logout() error { - m.log.Debugf("logout as %s (team: %s) on %s", m.Credentials.Login, m.Credentials.Team, m.Credentials.Server) + m.logger.Debugf("logout as %s (team: %s) on %s", m.Credentials.Login, m.Credentials.Team, m.Credentials.Server) m.WsQuit = true m.WsClient.Close() m.WsClient.UnderlyingConn().Close() if strings.Contains(m.Credentials.Pass, model.SESSION_COOKIE_TOKEN) { - m.log.Debug("Not invalidating session in logout, credential is a token") + m.logger.Debug("Not invalidating session in logout, credential is a token") return nil } _, resp := m.Client.Logout() @@ -147,13 +178,16 @@ func (m *MMClient) Logout() error { return nil } +// WsReceiver implements the core loop that manages the connection to the chat server. In +// case of a disconnect it will try to reconnect. A call to this method is blocking until +// the 'WsQuite' field of the MMClient object is set to 'true'. func (m *MMClient) WsReceiver() { for { var rawMsg json.RawMessage var err error if m.WsQuit { - m.log.Debug("exiting WsReceiver") + m.logger.Debug("exiting WsReceiver") return } @@ -163,14 +197,14 @@ func (m *MMClient) WsReceiver() { } if _, rawMsg, err = m.WsClient.ReadMessage(); err != nil { - m.log.Error("error:", err) + m.logger.Error("error:", err) // reconnect m.wsConnect() } var event model.WebSocketEvent if err := json.Unmarshal(rawMsg, &event); err == nil && event.IsValid() { - m.log.Debugf("WsReceiver event: %#v", event) + m.logger.Debugf("WsReceiver event: %#v", event) msg := &Message{Raw: &event, Team: m.Credentials.Team} m.parseMessage(msg) // check if we didn't empty the message @@ -189,40 +223,42 @@ func (m *MMClient) WsReceiver() { var response model.WebSocketResponse if err := json.Unmarshal(rawMsg, &response); err == nil && response.IsValid() { - m.log.Debugf("WsReceiver response: %#v", response) + m.logger.Debugf("WsReceiver response: %#v", response) m.parseResponse(response) - continue } } } +// StatusLoop implements a ping-cycle that ensures that the connection to the chat servers +// remains alive. In case of a disconnect it will try to reconnect. A call to this method +// is blocking until the 'WsQuite' field of the MMClient object is set to 'true'. func (m *MMClient) StatusLoop() { retries := 0 backoff := time.Second * 60 if m.OnWsConnect != nil { m.OnWsConnect() } - m.log.Debug("StatusLoop:", m.OnWsConnect != nil) + m.logger.Debug("StatusLoop:", m.OnWsConnect != nil) for { if m.WsQuit { return } if m.WsConnected { if err := m.checkAlive(); err != nil { - logrus.Errorf("Connection is not alive: %#v", err) + m.logger.Errorf("Connection is not alive: %#v", err) } select { case <-m.WsPingChan: - m.log.Debug("WS PONG received") + m.logger.Debug("WS PONG received") backoff = time.Second * 60 case <-time.After(time.Second * 5): if retries > 3 { - m.log.Debug("StatusLoop() timeout") + m.logger.Debug("StatusLoop() timeout") m.Logout() m.WsQuit = false err := m.Login() if err != nil { - logrus.Errorf("Login failed: %#v", err) + m.logger.Errorf("Login failed: %#v", err) break } if m.OnWsConnect != nil { |