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:
Simone Basso 2020-12-01 13:31:15 +01:00 committed by GitHub
parent cfd3b8f9b2
commit 2381c50dc5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 112 additions and 7 deletions

View File

@ -1,9 +1,8 @@
package main
import (
// commands
"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/info"
_ "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/version"
"github.com/ooni/probe-cli/internal/crashreport"
"github.com/ooni/probe-cli/internal/cli/app"
)
func main() {
err, _ := crashreport.CapturePanic(app.Run, nil)
if err != nil {
if err, _ := crashreport.CapturePanic(app.Run, nil); err != nil {
log.WithError(err.(error)).Error("panic in app.Run")
crashreport.Wait()
}

View File

@ -5,6 +5,7 @@ import (
"github.com/apex/log"
"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/syslog"
"github.com/ooni/probe-cli/internal/ooni"
"github.com/ooni/probe-cli/internal/utils"
"github.com/ooni/probe-cli/internal/version"
@ -33,6 +34,9 @@ func init() {
isVerbose := Cmd.Flag("verbose", "Enable verbose log output.").Short('v').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(
"software-name", "Override application name",
@ -42,10 +46,23 @@ func init() {
).Default(version.Version).String()
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 {
*logHandler = "batch"
}
switch *logHandler {
case "batch":
log.SetHandler(batch.Default)
} else {
case "cli", "":
log.SetHandler(cli.Default)
case "syslog":
log.SetHandler(syslog.Default)
default:
log.Fatalf("unknown --log-handler: %s", *logHandler)
}
if *isVerbose {
log.SetLevel(log.DebugLevel)

View 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
}

View 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
}