Initial Commit
This commit is contained in:
25
LICENSE
Normal file
25
LICENSE
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
Copyright (c) 2016, Dolf Schimmel - Freeaqingme
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||||
|
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
69
log/log.go
Normal file
69
log/log.go
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package log
|
||||||
|
|
||||||
|
import (
|
||||||
|
logging "github.com/op/go-logging"
|
||||||
|
"log"
|
||||||
|
"log/syslog"
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Logger struct {
|
||||||
|
*logging.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
Log *Logger
|
||||||
|
logFile string
|
||||||
|
)
|
||||||
|
|
||||||
|
func Open(name, logLevelStr string) *Logger {
|
||||||
|
logLevel, err := logging.LogLevel(logLevelStr)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Invalid log level specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
Log = &Logger { logging.MustGetLogger(name) }
|
||||||
|
|
||||||
|
var formatStdout = logging.MustStringFormatter(
|
||||||
|
"%{color}%{time:2006-01-02T15:04:05.000} %{shortfunc} ▶ %{level:.4s} %{color:reset} %{message}",
|
||||||
|
)
|
||||||
|
stdout := logging.NewLogBackend(os.Stdout, "", 0)
|
||||||
|
formatter := logging.NewBackendFormatter(stdout, formatStdout)
|
||||||
|
stdoutLeveled := logging.AddModuleLevel(formatter)
|
||||||
|
stdoutLeveled.SetLevel(logLevel, "")
|
||||||
|
syslogBackend, err := logging.NewSyslogBackendPriority("cluegetter", syslog.LOG_MAIL)
|
||||||
|
if err != nil {
|
||||||
|
Log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
logging.SetBackend(syslogBackend, stdoutLeveled)
|
||||||
|
|
||||||
|
return Log
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func Reopen(args string) {
|
||||||
|
if logFile == "" {
|
||||||
|
Log.Notice("Asked to reopen logs but running in foreground. Ignoring.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Log.Notice("Reopening log file per IPC request...")
|
||||||
|
logRedirectStdOutToFile(logFile)
|
||||||
|
Log.Notice("Reopened log file per IPC request")
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there are any existing fd's (e.g. we're reopening logs), we rely
|
||||||
|
// on garbage collection to clean them up for us.
|
||||||
|
func logRedirectStdOutToFile(logPath string) {
|
||||||
|
if logPath == "" {
|
||||||
|
Log.Fatal("Log Path not set")
|
||||||
|
}
|
||||||
|
|
||||||
|
logFile, err := os.OpenFile(logPath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644)
|
||||||
|
if err != nil {
|
||||||
|
Log.Fatal(err)
|
||||||
|
}
|
||||||
|
syscall.Dup2(int(logFile.Fd()), 1)
|
||||||
|
syscall.Dup2(int(logFile.Fd()), 2)
|
||||||
|
}
|
||||||
65
main.go
Normal file
65
main.go
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
package GoDaemonSkeleton
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
apps = make([]*App, 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
type App struct {
|
||||||
|
Name string
|
||||||
|
Handover *func()
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetApp() (*App, []string) {
|
||||||
|
appNames := func() []string {
|
||||||
|
out := []string{}
|
||||||
|
for _, app := range apps {
|
||||||
|
out = append(out, app.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(os.Args) < 2 {
|
||||||
|
fmt.Fprintf(os.Stderr, "No App specified. Must be one of: %s\n", strings.Join(appNames(), " "))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
var subAppArgs []string
|
||||||
|
var subApp *App
|
||||||
|
OuterLoop:
|
||||||
|
for i, arg := range os.Args[1:] {
|
||||||
|
for _, subAppTemp := range apps {
|
||||||
|
if arg == subAppTemp.Name {
|
||||||
|
subApp = subAppTemp
|
||||||
|
subAppArgs = os.Args[i+2:]
|
||||||
|
os.Args = os.Args[:i+1]
|
||||||
|
break OuterLoop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if subApp == nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "No App specified. Must be one of: %s\n", strings.Join(appNames(), " "))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return subApp, subAppArgs
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppRegister(app *App) {
|
||||||
|
if app == nil {
|
||||||
|
panic("nil subapp supplied")
|
||||||
|
}
|
||||||
|
for _, dup := range apps {
|
||||||
|
if dup.Name == app.Name {
|
||||||
|
panic("Register called twice for subApp " + app.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
apps = append(apps, app)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user