Skip to content

Commit

Permalink
Merge pull request #6 from perfecto25/logpath
Browse files Browse the repository at this point in the history
Logpath
  • Loading branch information
perfecto25 authored Oct 7, 2023
2 parents 0a0b472 + 1be9035 commit 2126619
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 76 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
/bin/
/.shards/
*.dwarf
config2*
config2.yaml
shard.lock
bin
25 changes: 21 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ see config.yaml for examples
rsync_opts: azBP ## additional Rsync flags (default: azP)
interval: 15 ## sleep time in seconds before rsyncing on a change, default = 10
recurse: true ## watch directories recursively for changes (ie, watch subdirectories), default = false
simulate: true ## show rsync actions in systemd log but dont do actual rsync or delete actions. default = true
simulate: true ## show rsync actions in log output, but dont do actual rsync or delete actions. default = true

"sync syslog to web9":
source_path: /var/log/syslog
Expand Down Expand Up @@ -106,12 +106,29 @@ if a Default value is not provided for port, interval, rsync_opts, and recurse,
- recurse = false
- simulate = true

---
### Logging

To use a custom Log file instead of standard output, add a "log_path" section in the config file,
Poni can log to either syslog or a custom log file

---
log_path: /path/to/your/logfile

log:
destination: stdout

or

log:
destination: /path/to/log/file

you can also set logging levels

log:
level: info

- info = will log all messages
- warning = will log only Warning and Error messages
- error = will only log Error messages
- debug = used for development of Poni

---

Expand Down
13 changes: 7 additions & 6 deletions config.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---

log_path: /var/log/poni # optional log path for Poni service, comment out this line to default to stdout
log:
destination: stdout # stdout or /path/to/log, ie /var/log/poni.log
level: error # info, error, warning, debug (for development)

### optional Global sync settings
defaults:
Expand All @@ -10,10 +11,10 @@ defaults:
remote_user: bob
priv_key: /home/bob/.ssh/id_rsa
rsync_opts: azP
interval: 3
recurse: false
port: 22
simulate: true
interval: 3
recurse: false
port: 22
simulate: true

## Remote syncs (can specify sync settings for each file or folder)
sync:
Expand Down
4 changes: 3 additions & 1 deletion shard.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: poni
version: 0.1.3
version: 0.1.4

authors:
- perfecto25
Expand All @@ -13,6 +13,8 @@ dependencies:
github: petoem/inotify.cr
schedule:
github: hugoabonizio/schedule.cr
logger:
github: crystal-lang/logger.cr

crystal: 1.2.1

Expand Down
43 changes: 32 additions & 11 deletions src/log.cr
Original file line number Diff line number Diff line change
@@ -1,17 +1,38 @@
require "log"
require "logger"

def init_log(cfg)
Log.setup do |c|
if cfg.has_key?("log_path")
begin
backend = Log::IOBackend.new(File.new(cfg["log_path"].as_s, "a+"))
rescue exception
abort "error creating log: #{exception}", 1
begin
if cfg.has_key?("log")
log_path = cfg["log"]["destination"].as_s.downcase

case log_path
when "stdout"
log = Logger.new(STDOUT)
else
file = File.new(log_path, "a")
writer = IO::MultiWriter.new(file, STDOUT)
log = Logger.new(writer)
end

level = cfg["log"]["level"].as_s.downcase
case level
when "info"
log.level = Logger::INFO
when "debug"
log.level = Logger::DEBUG
when "warning"
log.level = Logger::WARN
when "error"
log.level = Logger::ERROR
else
log.level = Logger::INFO
end
else
backend = Log::IOBackend.new
abort "No log destination or log level defined in config file"
end

c.bind "*", :debug, backend
end # log setup
log.progname = "Poni"
return log
rescue exception
abort exception, 1
end
end
57 changes: 22 additions & 35 deletions src/poni.cr
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# pp!
require "log"
require "option_parser"
require "inotify"
require "./watcher"
Expand All @@ -10,21 +9,20 @@ require "yaml"

module Poni
extend self
# Log::Severity = :debug
VERSION = "0.1.4"

VERSION = "0.1.3"
cfgfile = "/etc/poni/config.yml"

OptionParser.parse do |parser|
parser.banner = "Poni - inotify rsync daemon"
parser.on("-c CONFIG", "--config=CONFIG", "path to config file") { |config| cfgfile = config }
parser.on "-h", "--help", "Show help" do
puts parser
exit
STDOUT.puts parser
exit(0)
end
parser.on "-v", "--version", "Show version" do
puts VERSION
exit
STDOUT.puts VERSION
exit(0)
end
parser.invalid_option do |flag|
STDERR.puts "ERROR: #{flag} is not a valid option."
Expand All @@ -33,26 +31,15 @@ module Poni
end
end

begin
abort "config file is missing", 1 if !File.file? cfgfile
rescue exception
puts exception
end
abort "config file is missing", 1 if !File.file? cfgfile

begin
cfg = YAML.parse(File.read(cfgfile)).as_h
rescue exception
abort "unable to read config file", 1
end

begin
init_log(cfg)
rescue exception
abort exception, 1
end

Log = ::Log.for("Poni")

log = init_log(cfg)
channel = Channel(String).new

# # package default values, if not present in config.yaml
Expand All @@ -64,7 +51,7 @@ module Poni
"simulate": true,
}

def get_val(lookup, sync, data, cfg)
def get_val(lookup, sync, data, cfg, log)
if data.as_h.has_key?(lookup)
return data[lookup]?
end
Expand All @@ -80,7 +67,7 @@ module Poni
end

# exit if cant find lookup value
Log.error { "unable to find value for sync name: #{sync}, key: #{lookup}" }
log.error("unable to find value for sync name: #{sync}, key: #{lookup}")
abort "unable to find value for sync name: #{sync}, key: #{lookup}", 1
end

Expand All @@ -92,16 +79,16 @@ module Poni

# get sync values, if no value then use default fallback
cfg["sync"].as_h.each do |sync, data|
source_path = (get_val "source_path", sync, data, cfg).to_s
remote_host = (get_val "remote_host", sync, data, cfg).to_s
remote_path = (get_val "remote_path", sync, data, cfg).to_s
remote_user = (get_val "remote_user", sync, data, cfg).to_s
priv_key = (get_val "priv_key", sync, data, cfg).to_s
port = (get_val "port", sync, data, cfg).to_s
recurse = (get_val "recurse", sync, data, cfg).to_s
rsync_opts = (get_val "rsync_opts", sync, data, cfg).to_s
interval = (get_val "interval", sync, data, cfg).to_s
simulate = (get_val "simulate", sync, data, cfg).to_s
source_path = (get_val "source_path", sync, data, cfg, log).to_s
remote_host = (get_val "remote_host", sync, data, cfg, log).to_s
remote_path = (get_val "remote_path", sync, data, cfg, log).to_s
remote_user = (get_val "remote_user", sync, data, cfg, log).to_s
priv_key = (get_val "priv_key", sync, data, cfg, log).to_s
port = (get_val "port", sync, data, cfg, log).to_s
recurse = (get_val "recurse", sync, data, cfg, log).to_s
rsync_opts = (get_val "rsync_opts", sync, data, cfg, log).to_s
interval = (get_val "interval", sync, data, cfg, log).to_s
simulate = (get_val "simulate", sync, data, cfg, log).to_s

# for every source_path, create array of remote_paths and related data
arr = [] of Hash(String, String)
Expand Down Expand Up @@ -129,14 +116,14 @@ module Poni
# CREATE WATCHERS and SYNC SCHEDULERS
# iterate every source_path in Map, and spawn a watcher
map.each do |src_path, sync_data|
Watcher.spawn_watcher(src_path, sync_data, channel)
Watcher.spawn_watcher(src_path, sync_data, channel, log)
sync_now[src_path] = false
Scheduler.start_sched(src_path, sync_data, sync_now)
Scheduler.start_sched(src_path, sync_data, sync_now, log)
end

# CREATE SCHEDULERS
rescue exception
Log.fatal { exception }
log.error(exception)
abort "error running sync: #{exception}", 1
end # begin

Expand Down
14 changes: 6 additions & 8 deletions src/scheduler.cr
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
require "log"
require "schedule"
require "./poni"

# Scheduler starts running on startup, creates Scheduler runners that start rsync to remote whenever sync_now flag changes to True
# Signal to rsync comes from Poni main module, via Channel
# If Watcher fiber detects a modification, it alerts Poni main (via channel), which alters the sync_now flag to True

module Poni::Scheduler
extend self
Log = ::Log.for("Poni::Sched")

def start_sched(src_path, sync_data, sync_now)
def start_sched(src_path, sync_data, sync_now, log)
interval = DEFAULTS["interval"] # default

# get overal interval for single src_path spanning multiple remote paths
Expand All @@ -20,9 +17,9 @@ module Poni::Scheduler
if sync_now[src_path] == true
sync_data.each do |d|
if d["simulate"] == "true"
Log.info { "[SIMULATING] syncing #{src_path} >> #{d["remote_host"]}:#{d["remote_path"]} now." }
log.info("[SIMULATING] syncing #{src_path} >> #{d["remote_host"]}:#{d["remote_path"]} now.")
else
Log.info { "syncing #{src_path} >> #{d["remote_host"]}:#{d["remote_path"]} now." }
log.info("syncing #{src_path} >> #{d["remote_host"]}:#{d["remote_path"]} now.")
end

# # SYNC
Expand All @@ -41,12 +38,13 @@ module Poni::Scheduler
if d["simulate"] == "false"
exit_code = Process.run(command, shell: true, output: stdout, error: stderr).exit_code
if exit_code != 0
Log.error { "error syncing #{src_path} to #{d["remote_host"]}:#{d["remote_path"]}: #{stderr}" }
log.error("error syncing #{src_path} to #{d["remote_host"]}:#{d["remote_path"]}: #{stderr}")
end
end # simulate

rescue exception
Log.error { exception }
puts exception
log.error(exception)
end # begin

end # data.each
Expand Down
17 changes: 7 additions & 10 deletions src/watcher.cr
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
require "logger"
require "log"
# require "logger"
require "inotify"
require "schedule"

module Poni::Watcher
extend self
Log = ::Log.for("Poni::Watcher")

def spawn_watcher(src_path, data, channel)
Log.info { "watching #{src_path}" }

def spawn_watcher(src_path, data, channel, log)
log.info("watching #{src_path}")
recurse_bool = false
# if multiple remote_paths for same source_path, a single recurse=true means all recurse=true
data.each do |remote|
Expand All @@ -22,17 +19,17 @@ module Poni::Watcher
begin
Inotify.watch src_path, recurse_bool do |event|
if event.type.to_s == "MODIFY" || event.type.to_s == "CREATE"
Log.info { "#{event.name} (#{event.type}): source path: #{src_path}" }
log.info("#{event.name} (#{event.type}): source path: #{src_path}")
channel.send("#{event.type}, #{src_path}")
end

if event.type.to_s == "DELETE"
Log.info { "#{event.name} (#{event.type}): source path: #{src_path}" }
log.info("#{event.name} (#{event.type}): source path: #{src_path}")
end
end # event
rescue exception
Log.error { exception }
next
log.error("#{exception}, #{src_path}")
abort "#{exception}, #{src_path}", 1
end
end # spawn

Expand Down

0 comments on commit 2126619

Please sign in to comment.