Setting up HTTP server with configs and logging, updating gitignore, adding example watcher.

master
Patrick Kuti 9 years ago
parent bcfe641b5b
commit 5723801fbc

3
.gitignore vendored

@ -1,4 +1,3 @@
finspect
finspect.exe
*.tar.gz
*.zip
@ -7,4 +6,4 @@ finspect.exe
.idea/
.jshintrc
bin
.DS_Store
.DS_Store

@ -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…
Cancel
Save