feat: implement syslog logging (#181)
* feat: implement syslog logging With this functionality in tree, macOS users could easily access ooniprobe logs by filtering by process name in the console app. Part of https://github.com/ooni/probe/issues/1289 * fix: build on windows * fix: all build issues
This commit is contained in:
parent
cfd3b8f9b2
commit
2381c50dc5
|
@ -1,9 +1,8 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// commands
|
|
||||||
|
|
||||||
"github.com/apex/log"
|
"github.com/apex/log"
|
||||||
|
"github.com/ooni/probe-cli/internal/cli/app"
|
||||||
_ "github.com/ooni/probe-cli/internal/cli/geoip"
|
_ "github.com/ooni/probe-cli/internal/cli/geoip"
|
||||||
_ "github.com/ooni/probe-cli/internal/cli/info"
|
_ "github.com/ooni/probe-cli/internal/cli/info"
|
||||||
_ "github.com/ooni/probe-cli/internal/cli/list"
|
_ "github.com/ooni/probe-cli/internal/cli/list"
|
||||||
|
@ -15,13 +14,10 @@ import (
|
||||||
_ "github.com/ooni/probe-cli/internal/cli/upload"
|
_ "github.com/ooni/probe-cli/internal/cli/upload"
|
||||||
_ "github.com/ooni/probe-cli/internal/cli/version"
|
_ "github.com/ooni/probe-cli/internal/cli/version"
|
||||||
"github.com/ooni/probe-cli/internal/crashreport"
|
"github.com/ooni/probe-cli/internal/crashreport"
|
||||||
|
|
||||||
"github.com/ooni/probe-cli/internal/cli/app"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err, _ := crashreport.CapturePanic(app.Run, nil)
|
if err, _ := crashreport.CapturePanic(app.Run, nil); err != nil {
|
||||||
if err != nil {
|
|
||||||
log.WithError(err.(error)).Error("panic in app.Run")
|
log.WithError(err.(error)).Error("panic in app.Run")
|
||||||
crashreport.Wait()
|
crashreport.Wait()
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"github.com/apex/log"
|
"github.com/apex/log"
|
||||||
"github.com/ooni/probe-cli/internal/log/handlers/batch"
|
"github.com/ooni/probe-cli/internal/log/handlers/batch"
|
||||||
"github.com/ooni/probe-cli/internal/log/handlers/cli"
|
"github.com/ooni/probe-cli/internal/log/handlers/cli"
|
||||||
|
"github.com/ooni/probe-cli/internal/log/handlers/syslog"
|
||||||
"github.com/ooni/probe-cli/internal/ooni"
|
"github.com/ooni/probe-cli/internal/ooni"
|
||||||
"github.com/ooni/probe-cli/internal/utils"
|
"github.com/ooni/probe-cli/internal/utils"
|
||||||
"github.com/ooni/probe-cli/internal/version"
|
"github.com/ooni/probe-cli/internal/version"
|
||||||
|
@ -33,6 +34,9 @@ func init() {
|
||||||
|
|
||||||
isVerbose := Cmd.Flag("verbose", "Enable verbose log output.").Short('v').Bool()
|
isVerbose := Cmd.Flag("verbose", "Enable verbose log output.").Short('v').Bool()
|
||||||
isBatch := Cmd.Flag("batch", "Enable batch command line usage.").Bool()
|
isBatch := Cmd.Flag("batch", "Enable batch command line usage.").Bool()
|
||||||
|
logHandler := Cmd.Flag(
|
||||||
|
"log-handler", "Set the desired log handler (one of: batch, cli, syslog)",
|
||||||
|
).String()
|
||||||
|
|
||||||
softwareName := Cmd.Flag(
|
softwareName := Cmd.Flag(
|
||||||
"software-name", "Override application name",
|
"software-name", "Override application name",
|
||||||
|
@ -42,10 +46,23 @@ func init() {
|
||||||
).Default(version.Version).String()
|
).Default(version.Version).String()
|
||||||
|
|
||||||
Cmd.PreAction(func(ctx *kingpin.ParseContext) error {
|
Cmd.PreAction(func(ctx *kingpin.ParseContext) error {
|
||||||
|
// TODO(bassosimone): we need to properly deprecate --batch
|
||||||
|
// in favour of more granular command line flags.
|
||||||
|
if *isBatch && *logHandler != "" {
|
||||||
|
log.Fatal("cannot specify --batch and --log-handler together")
|
||||||
|
}
|
||||||
if *isBatch {
|
if *isBatch {
|
||||||
|
*logHandler = "batch"
|
||||||
|
}
|
||||||
|
switch *logHandler {
|
||||||
|
case "batch":
|
||||||
log.SetHandler(batch.Default)
|
log.SetHandler(batch.Default)
|
||||||
} else {
|
case "cli", "":
|
||||||
log.SetHandler(cli.Default)
|
log.SetHandler(cli.Default)
|
||||||
|
case "syslog":
|
||||||
|
log.SetHandler(syslog.Default)
|
||||||
|
default:
|
||||||
|
log.Fatalf("unknown --log-handler: %s", *logHandler)
|
||||||
}
|
}
|
||||||
if *isVerbose {
|
if *isVerbose {
|
||||||
log.SetLevel(log.DebugLevel)
|
log.SetLevel(log.DebugLevel)
|
||||||
|
|
39
internal/log/handlers/syslog/syslog.c
Normal file
39
internal/log/handlers/syslog/syslog.c
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <syslog.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void ooniprobe_openlog(void) {
|
||||||
|
#ifndef _WIN32
|
||||||
|
(void)openlog("ooniprobe", LOG_PID, LOG_USER);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ooniprobe_log_debug(const char *message) {
|
||||||
|
#ifndef _WIN32
|
||||||
|
(void)syslog(LOG_DEBUG, "%s", message);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ooniprobe_log_info(const char *message) {
|
||||||
|
#ifndef _WIN32
|
||||||
|
(void)syslog(LOG_INFO, "%s", message);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ooniprobe_log_warning(const char *message) {
|
||||||
|
#ifndef _WIN32
|
||||||
|
(void)syslog(LOG_WARNING, "%s", message);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ooniprobe_log_err(const char *message) {
|
||||||
|
#ifndef _WIN32
|
||||||
|
(void)syslog(LOG_ERR, "%s", message);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void ooniprobe_log_crit(const char *message) {
|
||||||
|
#ifndef _WIN32
|
||||||
|
(void)syslog(LOG_CRIT, "%s", message);
|
||||||
|
#endif
|
||||||
|
}
|
53
internal/log/handlers/syslog/syslog.go
Normal file
53
internal/log/handlers/syslog/syslog.go
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
// Package syslog contains a syslog handler.
|
||||||
|
//
|
||||||
|
// We use this handler on macOS systems to log messages
|
||||||
|
// when ooniprobe is running in the background.
|
||||||
|
package syslog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/apex/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include<stdlib.h>
|
||||||
|
|
||||||
|
void ooniprobe_openlog(void);
|
||||||
|
void ooniprobe_log_debug(const char *message);
|
||||||
|
void ooniprobe_log_info(const char *message);
|
||||||
|
void ooniprobe_log_warning(const char *message);
|
||||||
|
void ooniprobe_log_err(const char *message);
|
||||||
|
void ooniprobe_log_crit(const char *message);
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
// Default is the handler that emits logs with syslog
|
||||||
|
var Default log.Handler = newhandler()
|
||||||
|
|
||||||
|
type handler struct{}
|
||||||
|
|
||||||
|
func newhandler() handler {
|
||||||
|
C.ooniprobe_openlog()
|
||||||
|
return handler{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h handler) HandleLog(e *log.Entry) error {
|
||||||
|
message := fmt.Sprintf("%s %+v", e.Message, e.Fields)
|
||||||
|
cstr := C.CString(message)
|
||||||
|
defer C.free(unsafe.Pointer(cstr))
|
||||||
|
switch e.Level {
|
||||||
|
case log.DebugLevel:
|
||||||
|
C.ooniprobe_log_debug(cstr)
|
||||||
|
case log.InfoLevel:
|
||||||
|
C.ooniprobe_log_info(cstr)
|
||||||
|
case log.WarnLevel:
|
||||||
|
C.ooniprobe_log_warning(cstr)
|
||||||
|
case log.ErrorLevel:
|
||||||
|
C.ooniprobe_log_err(cstr)
|
||||||
|
default:
|
||||||
|
C.ooniprobe_log_crit(cstr)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user