Setting up HTTP server with configs and logging, updating gitignore, adding example watcher.
parent
bcfe641b5b
commit
5723801fbc
@ -1 +0,0 @@
|
|||||||
package main
|
|
@ -1 +0,0 @@
|
|||||||
package main
|
|
@ -0,0 +1,249 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
// Import needed packages
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/ant0ine/go-json-rest/rest"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Define finspect internal constants (TODO: move config_dir const to a command flag)
|
||||||
|
const (
|
||||||
|
FINSPECT_NAME string = "finspect"
|
||||||
|
FINSPECT_DESCRIPTION string = ""
|
||||||
|
FINSPECT_VERSION string = "0.0.1a"
|
||||||
|
FINSPECT_AUTHOR string = "Patrick Kuti <hello@introspect.in>"
|
||||||
|
FINSPECT_CONFIG_DIR string = "/etc/finspect/conf/"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Define log formats for finspect-http server
|
||||||
|
const (
|
||||||
|
CommonLogFormat = "%h %l %u %t \"%r\" %s %b" // CLR
|
||||||
|
CombinedLogFormat = "%h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-Agent}i\"" // NCSA extended/combined log format
|
||||||
|
DefaultLogFormat = "%t %S\033[0m \033[36;1m%Dμs\033[0m \"%r\" \033[1;30m%u \"%{User-Agent}i\"\033[0m" // Debug Format
|
||||||
|
)
|
||||||
|
|
||||||
|
// JSON struct for finspect-http server configuration
|
||||||
|
type Configuration struct {
|
||||||
|
LogDirectory string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variable for global finspect-http server configuration
|
||||||
|
var FinspectHttpConfiguration *Configuration = &Configuration{}
|
||||||
|
|
||||||
|
// setDefaults sets default values for the configuration struct
|
||||||
|
func (self *Configuration) setDefaults() {
|
||||||
|
self.LogDirectory = "/var/log/finspect/"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init parses configuration files, compiles global variables
|
||||||
|
// sets up logging and in general sets up the finspect-http server
|
||||||
|
func init() {
|
||||||
|
|
||||||
|
// Check if finspect server configuration file exists
|
||||||
|
FinspectHttpConfigurationFilePath := FINSPECT_CONFIG_DIR + "http.json"
|
||||||
|
_, err := os.Stat(FinspectHttpConfigurationFilePath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error looking for configuration file: " + FinspectHttpConfigurationFilePath)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set default configurations
|
||||||
|
FinspectHttpConfiguration.setDefaults()
|
||||||
|
|
||||||
|
// Attempt to load and parse json configuration file into global configuration variable
|
||||||
|
_loadConfig(FinspectHttpConfigurationFilePath)
|
||||||
|
|
||||||
|
// Check if log directory exists and is a directory
|
||||||
|
LogDirectory, err := os.Stat(FinspectHttpConfiguration.LogDirectory)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error trying to access log directory ("+FinspectHttpConfiguration.LogDirectory+"), error returned was: ", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if !LogDirectory.IsDir() {
|
||||||
|
log.Fatal("Log directory is not a directory, error returned was: ", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// _loadConfig loads values from a configuration file into global a configuration variable
|
||||||
|
func _loadConfig(FinspectHttpConfigurationFilePath string) {
|
||||||
|
|
||||||
|
// Try to open the finspect-http server configuration file and read it into global variable
|
||||||
|
FinspectHttpConfigurationFile, err := ioutil.ReadFile(FinspectHttpConfigurationFilePath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error reading configuration file, error returned was: ", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode JSON from configuration file and dump into configuration struct to override default values
|
||||||
|
err = json.Unmarshal(FinspectHttpConfigurationFile, FinspectHttpConfiguration)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error parsing configuration file, please ensure it is valid JSON. Error returned was: ", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main defines the available REST resources, starts up the finspect-http server
|
||||||
|
// along with various configuration options, settings and sets up logging
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// Default generic log handler
|
||||||
|
LogFileHandler, err := os.OpenFile(FinspectHttpConfiguration.LogDirectory+"http.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error trying to open general logfile, error returned was: ", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer LogFileHandler.Close()
|
||||||
|
log.SetOutput(LogFileHandler)
|
||||||
|
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
|
||||||
|
|
||||||
|
// HTTP access log handler
|
||||||
|
AccessLogFileHandler, err := os.OpenFile(FinspectHttpConfiguration.LogDirectory+"http-access.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error trying to open access logfile, error returned was: ", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer AccessLogFileHandler.Close()
|
||||||
|
|
||||||
|
// HTTP error log handler
|
||||||
|
ErrorLogFileHandler, err := os.OpenFile(FinspectHttpConfiguration.LogDirectory+"http-error.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error trying to open error logfile, error returned was: ", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
defer ErrorLogFileHandler.Close()
|
||||||
|
|
||||||
|
// Setting up configuration for the HTTP REST router
|
||||||
|
handler := rest.ResourceHandler{
|
||||||
|
EnableGzip: true,
|
||||||
|
DisableJsonIndent: false,
|
||||||
|
EnableStatusService: true,
|
||||||
|
EnableResponseStackTrace: true,
|
||||||
|
EnableLogAsJson: false,
|
||||||
|
EnableRelaxedContentType: false,
|
||||||
|
Logger: log.New(AccessLogFileHandler, "", 0),
|
||||||
|
LoggerFormat: CombinedLogFormat,
|
||||||
|
DisableLogger: false,
|
||||||
|
ErrorLogger: log.New(ErrorLogFileHandler, "", 0),
|
||||||
|
XPoweredBy: FINSPECT_NAME + " - " + FINSPECT_VERSION,
|
||||||
|
DisableXPoweredBy: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define some HTTP REST resources, log a fatal error if something goes wrong
|
||||||
|
err = handler.SetRoutes(
|
||||||
|
|
||||||
|
// Watcher related routes
|
||||||
|
&rest.Route{"GET", "/watchpaths", getReturnWatchPaths},
|
||||||
|
&rest.Route{"POST", "/watchpaths", postAddWatchPath},
|
||||||
|
&rest.Route{"DELETE", "/watchpaths/:watchpathid:", deleteRemoveWatchPath},
|
||||||
|
&rest.Route{"GET", "/watchpaths/:watchpathid:", getReturnWatchPath},
|
||||||
|
|
||||||
|
// Indexer related routes
|
||||||
|
&rest.Route{"POST", "/indexjobs", postAddIndexJob},
|
||||||
|
&rest.Route{"GET", "/indexjobs/:indexjobid:", getReturnIndexJob},
|
||||||
|
&rest.Route{"DELETE", "/indexjobs/:indexjobid:", deleteRemoveIndexJob},
|
||||||
|
&rest.Route{"POST", "/indexjobs/search", postSearchIndexJobs},
|
||||||
|
|
||||||
|
// Ingester related routes
|
||||||
|
&rest.Route{"POST", "/ingestjobs", postAddIngestJob},
|
||||||
|
&rest.Route{"GET", "/ingestjobs/:ingestjobid:", getReturnIngestJob},
|
||||||
|
&rest.Route{"DELETE", "/ingestjobs/:ingestjobid:", deleteRemoveIngestJob},
|
||||||
|
&rest.Route{"POST", "/ingestjobs/search", postSearchIngestJobs},
|
||||||
|
|
||||||
|
// File related routes
|
||||||
|
&rest.Route{"POST", "/files", postCreateFile},
|
||||||
|
|
||||||
|
// Admin and internally available resources
|
||||||
|
&rest.Route{"GET", "/.status", func(w rest.ResponseWriter, r *rest.Request) { w.WriteJson(handler.GetStatus()) }},
|
||||||
|
&rest.Route{"POST", "/shutdown", postAdminShutdownHttpServer},
|
||||||
|
&rest.Route{"POST", "/reload", postAdminReloadHttpServer},
|
||||||
|
&rest.Route{"POST", "/restart", postAdminRestartHttpServer},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Error with HTTP router, error returned was: ", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the finspect-http server
|
||||||
|
log.Fatal(http.ListenAndServe(":7070", &handler))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mock watcher functions
|
||||||
|
func getReturnWatchPaths(w rest.ResponseWriter, r *rest.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.WriteJson("OK")
|
||||||
|
}
|
||||||
|
func postAddWatchPath(w rest.ResponseWriter, r *rest.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.WriteJson("OK")
|
||||||
|
}
|
||||||
|
func deleteRemoveWatchPath(w rest.ResponseWriter, r *rest.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.WriteJson("OK")
|
||||||
|
}
|
||||||
|
func getReturnWatchPath(w rest.ResponseWriter, r *rest.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.WriteJson("OK")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mock indexer functions
|
||||||
|
func postAddIndexJob(w rest.ResponseWriter, r *rest.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.WriteJson("OK")
|
||||||
|
}
|
||||||
|
func getReturnIndexJob(w rest.ResponseWriter, r *rest.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.WriteJson("OK")
|
||||||
|
}
|
||||||
|
func deleteRemoveIndexJob(w rest.ResponseWriter, r *rest.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.WriteJson("OK")
|
||||||
|
}
|
||||||
|
func postSearchIndexJobs(w rest.ResponseWriter, r *rest.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.WriteJson("OK")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mock ingester functions
|
||||||
|
func postAddIngestJob(w rest.ResponseWriter, r *rest.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.WriteJson("OK")
|
||||||
|
}
|
||||||
|
func getReturnIngestJob(w rest.ResponseWriter, r *rest.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.WriteJson("OK")
|
||||||
|
}
|
||||||
|
func deleteRemoveIngestJob(w rest.ResponseWriter, r *rest.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.WriteJson("OK")
|
||||||
|
}
|
||||||
|
func postSearchIngestJobs(w rest.ResponseWriter, r *rest.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.WriteJson("OK")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mock files functions
|
||||||
|
func postCreateFile(w rest.ResponseWriter, r *rest.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.WriteJson("OK")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mock admin and internal functions
|
||||||
|
func postAdminShutdownHttpServer(w rest.ResponseWriter, r *rest.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.WriteJson("OK")
|
||||||
|
}
|
||||||
|
func postAdminReloadHttpServer(w rest.ResponseWriter, r *rest.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.WriteJson("OK")
|
||||||
|
}
|
||||||
|
func postAdminRestartHttpServer(w rest.ResponseWriter, r *rest.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.WriteJson("OK")
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
// Import needed packages
|
||||||
|
import (
|
||||||
|
"github.com/finspect/finspect"
|
||||||
|
"gopkg.in/fsnotify.v1"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Example watcher from fsnotify
|
||||||
|
func ExampleNewWatcher() {
|
||||||
|
watcher, err := fsnotify.NewWatcher()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer watcher.Close()
|
||||||
|
|
||||||
|
done := make(chan bool)
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case event := <-watcher.Events:
|
||||||
|
log.Println("event:", event)
|
||||||
|
if event.Op&fsnotify.Write == fsnotify.Write {
|
||||||
|
log.Println("modified file:", event.Name)
|
||||||
|
}
|
||||||
|
case err := <-watcher.Errors:
|
||||||
|
log.Println("error:", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
err = watcher.Add("/tmp")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
<-done
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ExampleNewWatcher()
|
||||||
|
}
|
Loading…
Reference in New Issue