improving logger to write to a file
This commit is contained in:
parent
3299ca0fb2
commit
bc9a40106c
56
client.go
56
client.go
@ -721,36 +721,53 @@ func (cts *ClientConn) AddClientRoutes(peer_addrs []string) error {
|
|||||||
|
|
||||||
for _, v = range peer_addrs {
|
for _, v = range peer_addrs {
|
||||||
va = strings.Split(v, ",")
|
va = strings.Split(v, ",")
|
||||||
if len(va) <= 0 || len(va) >= 4 {
|
if len(va) <= 0 { return fmt.Errorf("blank value") }
|
||||||
return fmt.Errorf("invalid address %v", va)
|
if len(va) >= 5 { return fmt.Errorf("too many fields in %v", v) }
|
||||||
}
|
|
||||||
|
|
||||||
_, port, err = net.SplitHostPort(va[0])
|
_, port, err = net.SplitHostPort(strings.TrimSpace(va[0]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid address %s", va[0], err.Error())
|
return fmt.Errorf("invalid address %s", va[0], err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(va) >= 2 {
|
if len(va) >= 2 {
|
||||||
_, _, err = net.SplitHostPort(va[1])
|
var f string
|
||||||
|
f = strings.TrimSpace(va[1])
|
||||||
|
_, _, err = net.SplitHostPort(f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid address %s", va[1], err.Error())
|
return fmt.Errorf("invalid address %s", va[1], err.Error())
|
||||||
}
|
}
|
||||||
svc_addr = va[1]
|
svc_addr = f
|
||||||
}
|
|
||||||
|
|
||||||
if len(va) >= 3 {
|
|
||||||
ptc_name = va[2]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
option = RouteOption(ROUTE_OPTION_TCP)
|
option = RouteOption(ROUTE_OPTION_TCP)
|
||||||
// automatic determination of protocol for common ports
|
if len(va) >= 3 {
|
||||||
switch port {
|
switch strings.ToLower(strings.TrimSpace(va[2])) {
|
||||||
case "22":
|
case "ssh":
|
||||||
option |= RouteOption(ROUTE_OPTION_SSH)
|
option |= RouteOption(ROUTE_OPTION_SSH)
|
||||||
case "80":
|
case "http":
|
||||||
option |= RouteOption(ROUTE_OPTION_HTTP)
|
option |= RouteOption(ROUTE_OPTION_HTTP)
|
||||||
case "443":
|
case "https":
|
||||||
option |= RouteOption(ROUTE_OPTION_HTTPS)
|
option |= RouteOption(ROUTE_OPTION_HTTPS)
|
||||||
|
|
||||||
|
case "":
|
||||||
|
fallthrough
|
||||||
|
case "auto":
|
||||||
|
// automatic determination of protocol for common ports
|
||||||
|
switch port {
|
||||||
|
case "22":
|
||||||
|
option |= RouteOption(ROUTE_OPTION_SSH)
|
||||||
|
case "80":
|
||||||
|
option |= RouteOption(ROUTE_OPTION_HTTP)
|
||||||
|
case "443":
|
||||||
|
option |= RouteOption(ROUTE_OPTION_HTTPS)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid option value %s", va[2])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(va) >= 4 {
|
||||||
|
ptc_name = strings.TrimSpace(va[3])
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = cts.AddNewClientRoute(va[0], ptc_name, svc_addr, "", option)
|
_, err = cts.AddNewClientRoute(va[0], ptc_name, svc_addr, "", option)
|
||||||
@ -1460,6 +1477,9 @@ func (c *Client) StopServices() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Client) FixServices() {
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) WaitForTermination() {
|
func (c *Client) WaitForTermination() {
|
||||||
c.wg.Wait()
|
c.wg.Wait()
|
||||||
}
|
}
|
||||||
|
81
cmd/main.go
81
cmd/main.go
@ -29,10 +29,30 @@ var hodul_tls_key_text []byte
|
|||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
type AppLogger struct {
|
type AppLogger struct {
|
||||||
id string
|
Id string
|
||||||
out io.Writer
|
Out io.Writer
|
||||||
mtx sync.Mutex
|
Mask hodu.LogMask
|
||||||
mask hodu.LogMask
|
|
||||||
|
_mtx sync.Mutex
|
||||||
|
_file *os.File
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAppLogger (id string, w io.Writer, mask hodu.LogMask) *AppLogger {
|
||||||
|
return &AppLogger{Id: id, Out: w, Mask: mask}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAppLoggerToFile (id string, file string, mask hodu.LogMask) (*AppLogger, error) {
|
||||||
|
var err error
|
||||||
|
var f *os.File
|
||||||
|
|
||||||
|
f, err = os.OpenFile(file, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
|
||||||
|
if err != nil { return nil, err }
|
||||||
|
|
||||||
|
return &AppLogger{Id: id, Out: f, Mask: mask, _file: f}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l* AppLogger) Close() {
|
||||||
|
if l._file != nil { l._file.Close() }
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l* AppLogger) Write(id string, level hodu.LogLevel, fmtstr string, args ...interface{}) {
|
func (l* AppLogger) Write(id string, level hodu.LogLevel, fmtstr string, args ...interface{}) {
|
||||||
@ -47,7 +67,7 @@ func (l* AppLogger) Write(id string, level hodu.LogLevel, fmtstr string, args ..
|
|||||||
var caller_line int
|
var caller_line int
|
||||||
var caller_ok bool
|
var caller_ok bool
|
||||||
|
|
||||||
if l.mask & hodu.LogMask(level) == 0 { return }
|
if l.Mask & hodu.LogMask(level) == 0 { return }
|
||||||
|
|
||||||
now = time.Now()
|
now = time.Now()
|
||||||
|
|
||||||
@ -65,20 +85,20 @@ func (l* AppLogger) Write(id string, level hodu.LogLevel, fmtstr string, args ..
|
|||||||
// TODO: add pid?
|
// TODO: add pid?
|
||||||
msg = fmt.Sprintf(fmtstr, args...)
|
msg = fmt.Sprintf(fmtstr, args...)
|
||||||
if id == "" {
|
if id == "" {
|
||||||
lid = fmt.Sprintf("%s: ", l.id)
|
lid = fmt.Sprintf("%s: ", l.Id)
|
||||||
} else {
|
} else {
|
||||||
lid = fmt.Sprintf("%s(%s): ", l.id, id)
|
lid = fmt.Sprintf("%s(%s): ", l.Id, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
l.mtx.Lock()
|
l._mtx.Lock()
|
||||||
l.out.Write([]byte(hdr))
|
l.Out.Write([]byte(hdr))
|
||||||
if caller_ok {
|
if caller_ok {
|
||||||
l.out.Write([]byte(fmt.Sprintf("[%s:%d] ", filepath.Base(caller_file), caller_line)))
|
l.Out.Write([]byte(fmt.Sprintf("[%s:%d] ", filepath.Base(caller_file), caller_line)))
|
||||||
}
|
}
|
||||||
if lid != "" { l.out.Write([]byte(lid)) }
|
if lid != "" { l.Out.Write([]byte(lid)) }
|
||||||
l.out.Write([]byte(msg))
|
l.Out.Write([]byte(msg))
|
||||||
if msg[len(msg) - 1] != '\n' { l.out.Write([]byte("\n")) }
|
if msg[len(msg) - 1] != '\n' { l.Out.Write([]byte("\n")) }
|
||||||
l.mtx.Unlock()
|
l._mtx.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
@ -105,8 +125,8 @@ chan_loop:
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-sighup_chan:
|
case <-sighup_chan:
|
||||||
// TODO:
|
sh.svc.FixServices()
|
||||||
//sh.svc.ReqReload()
|
|
||||||
case sig = <-sigterm_chan:
|
case sig = <-sigterm_chan:
|
||||||
sh.svc.StopServices()
|
sh.svc.StopServices()
|
||||||
sh.svc.WriteLog ("", hodu.LOG_INFO, "Received %s signal", sig)
|
sh.svc.WriteLog ("", hodu.LOG_INFO, "Received %s signal", sig)
|
||||||
@ -132,6 +152,9 @@ func (sh *signal_handler) StopServices() {
|
|||||||
syscall.Kill(syscall.Getpid(), syscall.SIGTERM) // TODO: find a better to terminate the signal handler...
|
syscall.Kill(syscall.Getpid(), syscall.SIGTERM) // TODO: find a better to terminate the signal handler...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sh *signal_handler) FixServices() {
|
||||||
|
}
|
||||||
|
|
||||||
func (sh *signal_handler) WaitForTermination() {
|
func (sh *signal_handler) WaitForTermination() {
|
||||||
// not implemented. see the comment in StartServices()
|
// not implemented. see the comment in StartServices()
|
||||||
// sh.wg.Wait()
|
// sh.wg.Wait()
|
||||||
@ -151,6 +174,7 @@ func server_main(ctl_addrs []string, rpc_addrs []string, pxy_addrs []string, cfg
|
|||||||
var ctl_prefix string
|
var ctl_prefix string
|
||||||
var logger *AppLogger
|
var logger *AppLogger
|
||||||
var log_mask hodu.LogMask
|
var log_mask hodu.LogMask
|
||||||
|
var log_file string
|
||||||
var max_rpc_conns int
|
var max_rpc_conns int
|
||||||
var max_peers int
|
var max_peers int
|
||||||
var err error
|
var err error
|
||||||
@ -179,6 +203,7 @@ func server_main(ctl_addrs []string, rpc_addrs []string, pxy_addrs []string, cfg
|
|||||||
|
|
||||||
ctl_prefix = cfg.CTL.Service.Prefix
|
ctl_prefix = cfg.CTL.Service.Prefix
|
||||||
log_mask = log_strings_to_mask(cfg.APP.LogMask)
|
log_mask = log_strings_to_mask(cfg.APP.LogMask)
|
||||||
|
log_file = cfg.APP.LogFile
|
||||||
max_rpc_conns = cfg.APP.MaxRpcConns
|
max_rpc_conns = cfg.APP.MaxRpcConns
|
||||||
max_peers = cfg.APP.MaxPeers
|
max_peers = cfg.APP.MaxPeers
|
||||||
}
|
}
|
||||||
@ -187,8 +212,15 @@ func server_main(ctl_addrs []string, rpc_addrs []string, pxy_addrs []string, cfg
|
|||||||
return fmt.Errorf("no rpc service addresses specified")
|
return fmt.Errorf("no rpc service addresses specified")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Change out field depending on cfg.APP.LogFile
|
if log_file == "" {
|
||||||
logger = &AppLogger{id: "server", out: os.Stderr, mask: log_mask}
|
logger = NewAppLogger("server", os.Stderr, log_mask)
|
||||||
|
} else {
|
||||||
|
logger, err = NewAppLoggerToFile("server", log_file, log_mask)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to initialize logger - %s", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
s, err = hodu.NewServer(
|
s, err = hodu.NewServer(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
logger,
|
logger,
|
||||||
@ -210,6 +242,7 @@ func server_main(ctl_addrs []string, rpc_addrs []string, pxy_addrs []string, cfg
|
|||||||
s.StartPxyService()
|
s.StartPxyService()
|
||||||
s.StartExtService(&signal_handler{svc:s}, nil)
|
s.StartExtService(&signal_handler{svc:s}, nil)
|
||||||
s.WaitForTermination()
|
s.WaitForTermination()
|
||||||
|
logger.Close()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -224,6 +257,7 @@ func client_main(ctl_addrs []string, rpc_addrs []string, peer_addrs []string, cf
|
|||||||
var cc hodu.ClientConfig
|
var cc hodu.ClientConfig
|
||||||
var logger *AppLogger
|
var logger *AppLogger
|
||||||
var log_mask hodu.LogMask
|
var log_mask hodu.LogMask
|
||||||
|
var log_file string
|
||||||
var max_rpc_conns int
|
var max_rpc_conns int
|
||||||
var max_peers int
|
var max_peers int
|
||||||
var peer_conn_tmout time.Duration
|
var peer_conn_tmout time.Duration
|
||||||
@ -247,6 +281,7 @@ func client_main(ctl_addrs []string, rpc_addrs []string, peer_addrs []string, cf
|
|||||||
cc.ServerSeedTmout = cfg.RPC.Endpoint.SeedTmout
|
cc.ServerSeedTmout = cfg.RPC.Endpoint.SeedTmout
|
||||||
cc.ServerAuthority = cfg.RPC.Endpoint.Authority
|
cc.ServerAuthority = cfg.RPC.Endpoint.Authority
|
||||||
log_mask = log_strings_to_mask(cfg.APP.LogMask)
|
log_mask = log_strings_to_mask(cfg.APP.LogMask)
|
||||||
|
log_file = cfg.APP.LogFile
|
||||||
max_rpc_conns = cfg.APP.MaxRpcConns
|
max_rpc_conns = cfg.APP.MaxRpcConns
|
||||||
max_peers = cfg.APP.MaxPeers
|
max_peers = cfg.APP.MaxPeers
|
||||||
peer_conn_tmout = cfg.APP.PeerConnTmout
|
peer_conn_tmout = cfg.APP.PeerConnTmout
|
||||||
@ -257,7 +292,14 @@ func client_main(ctl_addrs []string, rpc_addrs []string, peer_addrs []string, cf
|
|||||||
cc.ServerAddrs = rpc_addrs
|
cc.ServerAddrs = rpc_addrs
|
||||||
cc.PeerAddrs = peer_addrs
|
cc.PeerAddrs = peer_addrs
|
||||||
|
|
||||||
logger = &AppLogger{id: "client", out: os.Stderr, mask: log_mask}
|
if log_file == "" {
|
||||||
|
logger = NewAppLogger("server", os.Stderr, log_mask)
|
||||||
|
} else {
|
||||||
|
logger, err = NewAppLoggerToFile("server", log_file, log_mask)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to initialize logger - %s", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
c = hodu.NewClient(
|
c = hodu.NewClient(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
logger,
|
logger,
|
||||||
@ -273,6 +315,7 @@ func client_main(ctl_addrs []string, rpc_addrs []string, peer_addrs []string, cf
|
|||||||
c.StartCtlService() // control channel
|
c.StartCtlService() // control channel
|
||||||
c.StartExtService(&signal_handler{svc:c}, nil) // signal handler task
|
c.StartExtService(&signal_handler{svc:c}, nil) // signal handler task
|
||||||
c.WaitForTermination()
|
c.WaitForTermination()
|
||||||
|
logger.Close()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
1
hodu.go
1
hodu.go
@ -34,6 +34,7 @@ type Service interface {
|
|||||||
RunTask(wg *sync.WaitGroup) // blocking. run the actual task loop. it must call wg.Done() upon exit from itself.
|
RunTask(wg *sync.WaitGroup) // blocking. run the actual task loop. it must call wg.Done() upon exit from itself.
|
||||||
StartService(data interface{}) // non-blocking. spin up a service. it may be invokded multiple times for multiple instances
|
StartService(data interface{}) // non-blocking. spin up a service. it may be invokded multiple times for multiple instances
|
||||||
StopServices() // non-blocking. send stop request to all services spun up
|
StopServices() // non-blocking. send stop request to all services spun up
|
||||||
|
FixServices() // do some fixup as needed
|
||||||
WaitForTermination() // blocking. must wait until all services are stopped
|
WaitForTermination() // blocking. must wait until all services are stopped
|
||||||
WriteLog(id string, level LogLevel, fmtstr string, args ...interface{})
|
WriteLog(id string, level LogLevel, fmtstr string, args ...interface{})
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user