2014-07-27 02:37:18 +04:00
// Copyright 2014 The Gogs Authors. All rights reserved.
2019-04-02 10:48:31 +03:00
// Copyright 2019 The Gitea Authors. All rights reserved.
2014-07-27 02:37:18 +04:00
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package log
import (
2021-03-02 00:08:10 +03:00
"fmt"
2014-07-27 02:37:18 +04:00
"io"
"net"
2021-03-02 00:08:10 +03:00
jsoniter "github.com/json-iterator/go"
2014-07-27 02:37:18 +04:00
)
2019-04-02 10:48:31 +03:00
type connWriter struct {
2014-07-27 02:37:18 +04:00
innerWriter io . WriteCloser
ReconnectOnMsg bool ` json:"reconnectOnMsg" `
Reconnect bool ` json:"reconnect" `
Net string ` json:"net" `
Addr string ` json:"addr" `
}
2019-04-02 10:48:31 +03:00
// Close the inner writer
func ( i * connWriter ) Close ( ) error {
if i . innerWriter != nil {
return i . innerWriter . Close ( )
}
return nil
2014-07-27 02:37:18 +04:00
}
2019-04-02 10:48:31 +03:00
// Write the data to the connection
func ( i * connWriter ) Write ( p [ ] byte ) ( int , error ) {
if i . neededConnectOnMsg ( ) {
if err := i . connect ( ) ; err != nil {
return 0 , err
2014-07-27 02:37:18 +04:00
}
}
2019-04-02 10:48:31 +03:00
if i . ReconnectOnMsg {
defer i . innerWriter . Close ( )
2014-07-27 02:37:18 +04:00
}
2019-04-02 10:48:31 +03:00
return i . innerWriter . Write ( p )
2014-07-27 02:37:18 +04:00
}
2019-04-02 10:48:31 +03:00
func ( i * connWriter ) neededConnectOnMsg ( ) bool {
if i . Reconnect {
i . Reconnect = false
return true
2014-07-27 02:37:18 +04:00
}
2019-04-02 10:48:31 +03:00
if i . innerWriter == nil {
return true
}
return i . ReconnectOnMsg
2014-07-27 02:37:18 +04:00
}
2019-04-02 10:48:31 +03:00
func ( i * connWriter ) connect ( ) error {
if i . innerWriter != nil {
i . innerWriter . Close ( )
i . innerWriter = nil
2014-07-27 02:37:18 +04:00
}
2019-04-02 10:48:31 +03:00
conn , err := net . Dial ( i . Net , i . Addr )
2014-07-27 02:37:18 +04:00
if err != nil {
return err
}
if tcpConn , ok := conn . ( * net . TCPConn ) ; ok {
2019-06-12 22:41:28 +03:00
err = tcpConn . SetKeepAlive ( true )
if err != nil {
return err
}
2014-07-27 02:37:18 +04:00
}
2019-04-02 10:48:31 +03:00
i . innerWriter = conn
2014-07-27 02:37:18 +04:00
return nil
}
2020-07-06 03:07:07 +03:00
func ( i * connWriter ) releaseReopen ( ) error {
if i . innerWriter != nil {
return i . connect ( )
}
return nil
}
2019-04-02 10:48:31 +03:00
// ConnLogger implements LoggerProvider.
// it writes messages in keep-live tcp connection.
type ConnLogger struct {
2019-04-07 03:25:14 +03:00
WriterLogger
2019-04-02 10:48:31 +03:00
ReconnectOnMsg bool ` json:"reconnectOnMsg" `
Reconnect bool ` json:"reconnect" `
Net string ` json:"net" `
Addr string ` json:"addr" `
}
2014-07-27 02:37:18 +04:00
2019-04-02 10:48:31 +03:00
// NewConn creates new ConnLogger returning as LoggerProvider.
func NewConn ( ) LoggerProvider {
conn := new ( ConnLogger )
conn . Level = TRACE
return conn
}
// Init inits connection writer with json config.
// json config only need key "level".
func ( log * ConnLogger ) Init ( jsonconfig string ) error {
2021-03-02 00:08:10 +03:00
json := jsoniter . ConfigCompatibleWithStandardLibrary
2019-04-02 10:48:31 +03:00
err := json . Unmarshal ( [ ] byte ( jsonconfig ) , log )
if err != nil {
2021-03-02 00:08:10 +03:00
return fmt . Errorf ( "Unable to parse JSON: %v" , err )
2014-07-27 02:37:18 +04:00
}
2019-04-07 03:25:14 +03:00
log . NewWriterLogger ( & connWriter {
2019-04-02 10:48:31 +03:00
ReconnectOnMsg : log . ReconnectOnMsg ,
Reconnect : log . Reconnect ,
Net : log . Net ,
Addr : log . Addr ,
} , log . Level )
return nil
}
// Flush does nothing for this implementation
func ( log * ConnLogger ) Flush ( ) {
}
2014-07-27 02:37:18 +04:00
2019-04-02 10:48:31 +03:00
// GetName returns the default name for this implementation
func ( log * ConnLogger ) GetName ( ) string {
return "conn"
2014-07-27 02:37:18 +04:00
}
2020-07-06 03:07:07 +03:00
// ReleaseReopen causes the ConnLogger to reconnect to the server
func ( log * ConnLogger ) ReleaseReopen ( ) error {
return log . out . ( * connWriter ) . releaseReopen ( )
}
2014-07-27 02:37:18 +04:00
func init ( ) {
Register ( "conn" , NewConn )
}