Skip to content

Commit 7a6bc08

Browse files
committed
tt daemon: logger support
1 parent 0b88379 commit 7a6bc08

File tree

8 files changed

+198
-130
lines changed

8 files changed

+198
-130
lines changed

cli/cmd/daemon.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ func internalDaemonStartModule(cmdCtx *cmdcontext.CmdCtx, args []string) error {
108108
return err
109109
}
110110

111-
running.FillDaemonCtx(cliOpts, cmdCtx)
111+
if err = running.FillDaemonCtx(cliOpts, cmdCtx); err != nil {
112+
log.Fatalf(err.Error())
113+
}
112114

113115
if err := daemon.RunHTTPServerOnBackground(cmdCtx); err != nil {
114116
log.Fatalf(err.Error())
@@ -124,9 +126,9 @@ func internalDaemonStopModule(cmdCtx *cmdcontext.CmdCtx, args []string) error {
124126
return err
125127
}
126128

127-
running.FillDaemonCtx(cliOpts, cmdCtx)
128-
129-
daemon.StopHTTPServer(cmdCtx)
129+
if err = running.FillDaemonCtx(cliOpts, cmdCtx); err != nil {
130+
log.Fatalf(err.Error())
131+
}
130132

131133
if err := running.Stop(cmdCtx, cmdCtx.Daemon.PIDFile, cmdCtx.Daemon.ConsoleSocket); err != nil {
132134
return err
@@ -142,7 +144,9 @@ func internalDaemonStatusModule(cmdCtx *cmdcontext.CmdCtx, args []string) error
142144
return err
143145
}
144146

145-
running.FillDaemonCtx(cliOpts, cmdCtx)
147+
if err = running.FillDaemonCtx(cliOpts, cmdCtx); err != nil {
148+
log.Fatalf(err.Error())
149+
}
146150

147151
log.Info(running.Status(cmdCtx, cmdCtx.Daemon.PIDFile))
148152

cli/cmdcontext/cmdcontext.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,20 @@ type ConnectCtx struct {
8989
type DaemonCtx struct {
9090
Port int
9191
PIDFile string
92+
LogPath string
93+
// LogMaxSize is the maximum size in megabytes of the log file
94+
// before it gets rotated. It defaults to 100 megabytes.
95+
LogMaxSize int
96+
// LogMaxBackups is the maximum number of old log files to retain.
97+
// The default is to retain all old log files (though LogMaxAge may
98+
// still cause them to get deleted).
99+
LogMaxBackups int
100+
// LogMaxAge is the maximum number of days to retain old log files
101+
// based on the timestamp encoded in their filename. Note that a
102+
// day is defined as 24 hours and may not exactly correspond to
103+
// calendar days due to daylight savings, leap seconds, etc. The
104+
// default is not to remove old log files based on age.
105+
LogMaxAge int
92106
ConsoleSocket string
107+
ListenInterface string
93108
}

cli/config/config.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,20 @@ type AppOpts struct {
6464
type DaemonOpts struct {
6565
PIDFile string `mapstructure:"pid"`
6666
Port int `mapstructure:"port"`
67+
LogDir string `mapstructure:"log_dir"`
68+
LogFile string `mapstructure:"log_file"`
69+
LogMaxSize int `mapstructure:"log_maxsize"`
70+
// LogMaxAge is the maximum number of days to retain old log files
71+
// based on the timestamp encoded in their filename. Note that a
72+
// day is defined as 24 hours and may not exactly correspond to
73+
// calendar days due to daylight savings, leap seconds, etc. The
74+
// default is not to remove old log files based on age.
75+
LogMaxAge int `mapstructure:"log_maxage"`
76+
// LogMaxBackups is the maximum number of old log files to retain.
77+
// The default is to retain all old log files (though LogMaxAge may
78+
// still cause them to get deleted).
79+
LogMaxBackups int `mapstructure:"log_maxbackups"`
80+
ListenInterface string `mapstructure:"listen_interface"`
6781
}
6882

6983
// CliOpts is used to store modules and app options.

cli/configure/configure.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ const (
2222
cliExecutableName = "tt"
2323
)
2424

25+
const (
26+
defaultDaemonPort = 1024
27+
defaultDaemonPidFile = "tt_daemon.pid"
28+
defaultDaemonLogFile= "tt_daemon.log"
29+
)
30+
2531
var (
2632
// Path to default tarantool.yaml configuration file.
2733
// Defined at build time, see magefile.
@@ -43,7 +49,18 @@ func getDefaultCliOpts() *config.CliOpts {
4349
Restartable: false,
4450
DataDir: "data",
4551
}
46-
return &config.CliOpts{Modules: &modules, App: &app}
52+
daemon := config.DaemonOpts{
53+
Port: defaultDaemonPort,
54+
PIDFile: defaultDaemonPidFile,
55+
LogDir: "log",
56+
LogFile: defaultDaemonLogFile,
57+
LogMaxSize: 0,
58+
LogMaxAge: 0,
59+
LogMaxBackups: 0,
60+
ListenInterface: "",
61+
}
62+
63+
return &config.CliOpts{Modules: &modules, App: &app, Daemon: &daemon}
4764
}
4865

4966
// GetCliOpts returns Tarantool CLI options from the config file

cli/daemon/daemon.go

Lines changed: 8 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,23 @@
11
package daemon
22

33
import (
4-
"fmt"
5-
"net"
6-
"os"
7-
"strconv"
8-
"syscall"
9-
104
"github.com/tarantool/tt/cli/cmdcontext"
11-
"github.com/tarantool/tt/cli/running"
5+
"github.com/tarantool/tt/cli/ttlog"
126
)
137

14-
func externalIP() (string, error) {
15-
ifaces, err := net.Interfaces()
16-
if err != nil {
17-
return "", err
18-
}
19-
20-
for _, iface := range ifaces {
21-
if iface.Flags & net.FlagUp == 0 {
22-
continue // interface down
23-
}
24-
if iface.Flags & net.FlagLoopback != 0 {
25-
continue // loopback interface
26-
}
27-
28-
addrs, err := iface.Addrs()
29-
if err != nil {
30-
return "", err
31-
}
32-
33-
for _, addr := range addrs {
34-
var ip net.IP
35-
switch v := addr.(type) {
36-
case *net.IPNet:
37-
ip = v.IP
38-
case *net.IPAddr:
39-
ip = v.IP
40-
}
41-
42-
if ip == nil || ip.IsLoopback() {
43-
continue
44-
}
45-
46-
ip = ip.To4()
47-
if ip == nil {
48-
continue // not an ipv4 address
49-
}
50-
51-
return ip.String(), nil
52-
}
53-
}
54-
55-
return "", fmt.Errorf("external IP is not available")
56-
}
57-
588
func RunHTTPServerOnBackground(cmdCtx *cmdcontext.CmdCtx) error {
59-
ip, err := externalIP()
60-
if err != nil {
61-
return err
9+
logOpts := ttlog.LoggerOpts{
10+
Filename: cmdCtx.Daemon.LogPath,
11+
MaxSize: cmdCtx.Daemon.LogMaxSize,
12+
MaxBackups: cmdCtx.Daemon.LogMaxBackups,
13+
MaxAge: cmdCtx.Daemon.LogMaxAge,
6214
}
6315

64-
httpServerAddr := ip + ":" + strconv.Itoa(cmdCtx.Daemon.Port)
65-
proc := NewProcess(NewHTTPServer(httpServerAddr), cmdCtx.Daemon.PIDFile)
16+
proc := NewProcess(NewHTTPServer(cmdCtx.Daemon.ListenInterface, cmdCtx.Daemon.Port),
17+
cmdCtx.Daemon.PIDFile, logOpts)
6618

6719
if err := proc.Start(); err != nil {
6820
return err
6921
}
7022
return nil
7123
}
72-
73-
func SendSignalToDaemon(pidFile string, sig os.Signal) error {
74-
pid, err := running.GetPIDFromFile(pidFile)
75-
if err != nil {
76-
return err
77-
}
78-
79-
process, err := os.FindProcess(pid)
80-
if err != nil {
81-
return err
82-
}
83-
84-
err = process.Signal(sig)
85-
return err
86-
}
87-
88-
func StopHTTPServer(cmdCtx *cmdcontext.CmdCtx) error {
89-
err := SendSignalToDaemon(cmdCtx.Daemon.PIDFile, syscall.SIGUSR1)
90-
return err
91-
}

cli/daemon/httpserver.go

Lines changed: 84 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,78 @@ package daemon
22

33
import (
44
"context"
5-
"log"
5+
"fmt"
6+
"net"
67
"net/http"
8+
"strconv"
79
"time"
810

911
"github.com/tarantool/tt/cli/daemon/api"
12+
"github.com/tarantool/tt/cli/ttlog"
1013
)
1114

1215
const (
1316
defaultStopTimeout = 100 * time.Millisecond
1417
)
1518

1619
type HTTPServer struct {
17-
srv *http.Server
18-
timeout time.Duration
20+
listenIface string
21+
port int
22+
srv *http.Server
23+
timeout time.Duration
24+
logger *ttlog.Logger
1925
}
2026

21-
func NewHTTPServer(httpServerAddr string) *HTTPServer {
27+
func (httpServer *HTTPServer) externalIP() (string, error) {
28+
if httpServer.listenIface == "" {
29+
return net.IPv4zero.String(), nil
30+
}
31+
32+
iface, err := net.InterfaceByName(httpServer.listenIface)
33+
if err != nil {
34+
return "", err
35+
}
36+
37+
if iface.Flags & net.FlagUp == 0 {
38+
return "", fmt.Errorf("Interface down")
39+
}
40+
if iface.Flags & net.FlagLoopback != 0 {
41+
return "", fmt.Errorf("Loopback interface")
42+
}
43+
44+
addrs, err := iface.Addrs()
45+
if err != nil {
46+
return "", err
47+
}
48+
49+
for _, addr := range addrs {
50+
var ip net.IP
51+
switch v := addr.(type) {
52+
case *net.IPNet:
53+
ip = v.IP
54+
case *net.IPAddr:
55+
ip = v.IP
56+
}
57+
58+
if ip == nil || ip.IsLoopback() {
59+
continue
60+
}
61+
62+
ip = ip.To4()
63+
if ip == nil {
64+
continue // not an ipv4 address
65+
}
66+
67+
return ip.String(), nil
68+
}
69+
70+
return "", fmt.Errorf("external IP is not available")
71+
}
72+
73+
func NewHTTPServer(listenInterface string, port int) *HTTPServer {
2274
return &HTTPServer{
23-
srv: &http.Server{
24-
Addr: httpServerAddr,
25-
},
75+
listenIface: listenInterface,
76+
port: port,
2677
timeout: defaultStopTimeout,
2778
}
2879
}
@@ -32,23 +83,46 @@ func (httpServer *HTTPServer) Timeout(timeout time.Duration) *HTTPServer {
3283
return httpServer
3384
}
3485

86+
func (httpServer *HTTPServer) SetLogger(logger *ttlog.Logger) {
87+
httpServer.logger = logger
88+
}
89+
3590
func (httpServer *HTTPServer) Start(ttPath string) {
91+
ip, err := httpServer.externalIP()
92+
if err != nil {
93+
httpServer.logger.Fatalf("Can't get IP")
94+
}
95+
96+
httpServerAddr := ip + ":" + strconv.Itoa(httpServer.port)
97+
httpServer.srv = &http.Server{
98+
Addr: httpServerAddr,
99+
}
100+
36101
// Prepare HTTP server.
37102
daemonHandler := api.NewDaemonHandler(ttPath)
38103
http.Handle("/tarantool", daemonHandler)
39104

40105
// Start HTTP server.
41-
if err := httpServer.srv.ListenAndServe(); err != http.ErrServerClosed {
42-
log.Fatalf("Can't start HTTP server")
106+
socket, err := net.Listen("tcp4", httpServer.srv.Addr)
107+
if err != nil {
108+
httpServer.logger.Fatal(err)
109+
}
110+
111+
if err := httpServer.srv.Serve(socket); err != http.ErrServerClosed {
112+
httpServer.logger.Fatalf("Can't start HTTP server")
43113
}
44114
}
45115

46116
func (httpServer *HTTPServer) Stop() error {
47117
var err error
48118

119+
if httpServer.srv == nil {
120+
return fmt.Errorf("Server is not started")
121+
}
122+
49123
ctx, cancel := context.WithTimeout(context.Background(), httpServer.timeout)
50124
if err = httpServer.srv.Shutdown(ctx); err != nil {
51-
log.Printf(`HTTP server shutdown error: "%v"`, err)
125+
httpServer.logger.Printf(`HTTP server shutdown error: "%v"`, err)
52126
}
53127
cancel()
54128

0 commit comments

Comments
 (0)