Skip to content

Commit 2126619

Browse files
authored
Merge pull request #6 from perfecto25/logpath
Logpath
2 parents 0a0b472 + 1be9035 commit 2126619

8 files changed

+99
-76
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
/bin/
44
/.shards/
55
*.dwarf
6-
config2*
6+
config2.yaml
77
shard.lock
88
bin

README.md

+21-4
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ see config.yaml for examples
6969
rsync_opts: azBP ## additional Rsync flags (default: azP)
7070
interval: 15 ## sleep time in seconds before rsyncing on a change, default = 10
7171
recurse: true ## watch directories recursively for changes (ie, watch subdirectories), default = false
72-
simulate: true ## show rsync actions in systemd log but dont do actual rsync or delete actions. default = true
72+
simulate: true ## show rsync actions in log output, but dont do actual rsync or delete actions. default = true
7373

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

109+
---
110+
### Logging
109111

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

112114
---
113-
log_path: /path/to/your/logfile
114-
115+
log:
116+
destination: stdout
117+
118+
or
119+
120+
log:
121+
destination: /path/to/log/file
122+
123+
you can also set logging levels
124+
125+
log:
126+
level: info
127+
128+
- info = will log all messages
129+
- warning = will log only Warning and Error messages
130+
- error = will only log Error messages
131+
- debug = used for development of Poni
115132

116133
---
117134

config.yml

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
2-
3-
log_path: /var/log/poni # optional log path for Poni service, comment out this line to default to stdout
2+
log:
3+
destination: stdout # stdout or /path/to/log, ie /var/log/poni.log
4+
level: error # info, error, warning, debug (for development)
45

56
### optional Global sync settings
67
defaults:
@@ -10,10 +11,10 @@ defaults:
1011
remote_user: bob
1112
priv_key: /home/bob/.ssh/id_rsa
1213
rsync_opts: azP
13-
interval: 3
14-
recurse: false
15-
port: 22
16-
simulate: true
14+
interval: 3
15+
recurse: false
16+
port: 22
17+
simulate: true
1718

1819
## Remote syncs (can specify sync settings for each file or folder)
1920
sync:

shard.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: poni
2-
version: 0.1.3
2+
version: 0.1.4
33

44
authors:
55
- perfecto25
@@ -13,6 +13,8 @@ dependencies:
1313
github: petoem/inotify.cr
1414
schedule:
1515
github: hugoabonizio/schedule.cr
16+
logger:
17+
github: crystal-lang/logger.cr
1618

1719
crystal: 1.2.1
1820

src/log.cr

+32-11
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,38 @@
1-
require "log"
1+
require "logger"
22

33
def init_log(cfg)
4-
Log.setup do |c|
5-
if cfg.has_key?("log_path")
6-
begin
7-
backend = Log::IOBackend.new(File.new(cfg["log_path"].as_s, "a+"))
8-
rescue exception
9-
abort "error creating log: #{exception}", 1
4+
begin
5+
if cfg.has_key?("log")
6+
log_path = cfg["log"]["destination"].as_s.downcase
7+
8+
case log_path
9+
when "stdout"
10+
log = Logger.new(STDOUT)
11+
else
12+
file = File.new(log_path, "a")
13+
writer = IO::MultiWriter.new(file, STDOUT)
14+
log = Logger.new(writer)
15+
end
16+
17+
level = cfg["log"]["level"].as_s.downcase
18+
case level
19+
when "info"
20+
log.level = Logger::INFO
21+
when "debug"
22+
log.level = Logger::DEBUG
23+
when "warning"
24+
log.level = Logger::WARN
25+
when "error"
26+
log.level = Logger::ERROR
27+
else
28+
log.level = Logger::INFO
1029
end
1130
else
12-
backend = Log::IOBackend.new
31+
abort "No log destination or log level defined in config file"
1332
end
14-
15-
c.bind "*", :debug, backend
16-
end # log setup
33+
log.progname = "Poni"
34+
return log
35+
rescue exception
36+
abort exception, 1
37+
end
1738
end

src/poni.cr

+22-35
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
# pp!
2-
require "log"
32
require "option_parser"
43
require "inotify"
54
require "./watcher"
@@ -10,21 +9,20 @@ require "yaml"
109

1110
module Poni
1211
extend self
13-
# Log::Severity = :debug
12+
VERSION = "0.1.4"
1413

15-
VERSION = "0.1.3"
1614
cfgfile = "/etc/poni/config.yml"
1715

1816
OptionParser.parse do |parser|
1917
parser.banner = "Poni - inotify rsync daemon"
2018
parser.on("-c CONFIG", "--config=CONFIG", "path to config file") { |config| cfgfile = config }
2119
parser.on "-h", "--help", "Show help" do
22-
puts parser
23-
exit
20+
STDOUT.puts parser
21+
exit(0)
2422
end
2523
parser.on "-v", "--version", "Show version" do
26-
puts VERSION
27-
exit
24+
STDOUT.puts VERSION
25+
exit(0)
2826
end
2927
parser.invalid_option do |flag|
3028
STDERR.puts "ERROR: #{flag} is not a valid option."
@@ -33,26 +31,15 @@ module Poni
3331
end
3432
end
3533

36-
begin
37-
abort "config file is missing", 1 if !File.file? cfgfile
38-
rescue exception
39-
puts exception
40-
end
34+
abort "config file is missing", 1 if !File.file? cfgfile
4135

4236
begin
4337
cfg = YAML.parse(File.read(cfgfile)).as_h
4438
rescue exception
4539
abort "unable to read config file", 1
4640
end
4741

48-
begin
49-
init_log(cfg)
50-
rescue exception
51-
abort exception, 1
52-
end
53-
54-
Log = ::Log.for("Poni")
55-
42+
log = init_log(cfg)
5643
channel = Channel(String).new
5744

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

67-
def get_val(lookup, sync, data, cfg)
54+
def get_val(lookup, sync, data, cfg, log)
6855
if data.as_h.has_key?(lookup)
6956
return data[lookup]?
7057
end
@@ -80,7 +67,7 @@ module Poni
8067
end
8168

8269
# exit if cant find lookup value
83-
Log.error { "unable to find value for sync name: #{sync}, key: #{lookup}" }
70+
log.error("unable to find value for sync name: #{sync}, key: #{lookup}")
8471
abort "unable to find value for sync name: #{sync}, key: #{lookup}", 1
8572
end
8673

@@ -92,16 +79,16 @@ module Poni
9279

9380
# get sync values, if no value then use default fallback
9481
cfg["sync"].as_h.each do |sync, data|
95-
source_path = (get_val "source_path", sync, data, cfg).to_s
96-
remote_host = (get_val "remote_host", sync, data, cfg).to_s
97-
remote_path = (get_val "remote_path", sync, data, cfg).to_s
98-
remote_user = (get_val "remote_user", sync, data, cfg).to_s
99-
priv_key = (get_val "priv_key", sync, data, cfg).to_s
100-
port = (get_val "port", sync, data, cfg).to_s
101-
recurse = (get_val "recurse", sync, data, cfg).to_s
102-
rsync_opts = (get_val "rsync_opts", sync, data, cfg).to_s
103-
interval = (get_val "interval", sync, data, cfg).to_s
104-
simulate = (get_val "simulate", sync, data, cfg).to_s
82+
source_path = (get_val "source_path", sync, data, cfg, log).to_s
83+
remote_host = (get_val "remote_host", sync, data, cfg, log).to_s
84+
remote_path = (get_val "remote_path", sync, data, cfg, log).to_s
85+
remote_user = (get_val "remote_user", sync, data, cfg, log).to_s
86+
priv_key = (get_val "priv_key", sync, data, cfg, log).to_s
87+
port = (get_val "port", sync, data, cfg, log).to_s
88+
recurse = (get_val "recurse", sync, data, cfg, log).to_s
89+
rsync_opts = (get_val "rsync_opts", sync, data, cfg, log).to_s
90+
interval = (get_val "interval", sync, data, cfg, log).to_s
91+
simulate = (get_val "simulate", sync, data, cfg, log).to_s
10592

10693
# for every source_path, create array of remote_paths and related data
10794
arr = [] of Hash(String, String)
@@ -129,14 +116,14 @@ module Poni
129116
# CREATE WATCHERS and SYNC SCHEDULERS
130117
# iterate every source_path in Map, and spawn a watcher
131118
map.each do |src_path, sync_data|
132-
Watcher.spawn_watcher(src_path, sync_data, channel)
119+
Watcher.spawn_watcher(src_path, sync_data, channel, log)
133120
sync_now[src_path] = false
134-
Scheduler.start_sched(src_path, sync_data, sync_now)
121+
Scheduler.start_sched(src_path, sync_data, sync_now, log)
135122
end
136123

137124
# CREATE SCHEDULERS
138125
rescue exception
139-
Log.fatal { exception }
126+
log.error(exception)
140127
abort "error running sync: #{exception}", 1
141128
end # begin
142129

src/scheduler.cr

+6-8
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
1-
require "log"
21
require "schedule"
3-
require "./poni"
42

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

97
module Poni::Scheduler
108
extend self
11-
Log = ::Log.for("Poni::Sched")
129

13-
def start_sched(src_path, sync_data, sync_now)
10+
def start_sched(src_path, sync_data, sync_now, log)
1411
interval = DEFAULTS["interval"] # default
1512

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

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

4845
rescue exception
49-
Log.error { exception }
46+
puts exception
47+
log.error(exception)
5048
end # begin
5149

5250
end # data.each

src/watcher.cr

+7-10
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
require "logger"
2-
require "log"
1+
# require "logger"
32
require "inotify"
43
require "schedule"
54

65
module Poni::Watcher
76
extend self
8-
Log = ::Log.for("Poni::Watcher")
9-
10-
def spawn_watcher(src_path, data, channel)
11-
Log.info { "watching #{src_path}" }
127

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

2926
if event.type.to_s == "DELETE"
30-
Log.info { "#{event.name} (#{event.type}): source path: #{src_path}" }
27+
log.info("#{event.name} (#{event.type}): source path: #{src_path}")
3128
end
3229
end # event
3330
rescue exception
34-
Log.error { exception }
35-
next
31+
log.error("#{exception}, #{src_path}")
32+
abort "#{exception}, #{src_path}", 1
3633
end
3734
end # spawn
3835

0 commit comments

Comments
 (0)