tumugi 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -2
- data/lib/tumugi.rb +1 -1
- data/lib/tumugi/cli.rb +22 -16
- data/lib/tumugi/command/new.rb +1 -1
- data/lib/tumugi/command/run.rb +4 -4
- data/lib/tumugi/command/show.rb +1 -1
- data/lib/tumugi/config.rb +2 -2
- data/lib/tumugi/executor/local_executor.rb +16 -21
- data/lib/tumugi/{logger.rb → logger/logger.rb} +9 -12
- data/lib/tumugi/logger/scoped_logger.rb +43 -0
- data/lib/tumugi/mixin/parameterizable.rb +1 -1
- data/lib/tumugi/target.rb +1 -1
- data/lib/tumugi/task.rb +2 -1
- data/lib/tumugi/task_definition.rb +1 -1
- data/lib/tumugi/version.rb +1 -1
- data/lib/tumugi/workflow.rb +20 -7
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e012701afe6c29a35dd59f9c380c7a2e8b350c76
|
4
|
+
data.tar.gz: 2a2e156e12b4977a3148a8e6d8fd5329d7691083
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3fa3d8aa768b6a70da18cd765cacbb8dedf2186d9b64d9784dcefe03cd13e422e24021a92a408904385861c29f986a748ecaf8780bd4455427cb584da6f5e531
|
7
|
+
data.tar.gz: 219ba5614c9726fbd5c06bac22c735ed6056f7d8a0a808519bbd4040056a4736be36506303390b6d3d54667c47c5bfa5e68975298437c81da583941d9c7143cd
|
data/CHANGELOG.md
CHANGED
@@ -1,10 +1,26 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
## [
|
4
|
-
[Full Changelog](https://github.com/tumugi/tumugi/compare/v0.6.
|
3
|
+
## [v0.6.2](https://github.com/tumugi/tumugi/tree/v0.6.2) (2016-08-02)
|
4
|
+
[Full Changelog](https://github.com/tumugi/tumugi/compare/v0.6.1...v0.6.2)
|
5
|
+
|
6
|
+
**Implemented enhancements:**
|
7
|
+
|
8
|
+
- Improve Log output [\#105](https://github.com/tumugi/tumugi/issues/105)
|
9
|
+
|
10
|
+
**Fixed bugs:**
|
11
|
+
|
12
|
+
- tumugi should abort when config file not found [\#108](https://github.com/tumugi/tumugi/issues/108)
|
13
|
+
|
14
|
+
**Merged pull requests:**
|
15
|
+
|
16
|
+
- Improve and change logging [\#107](https://github.com/tumugi/tumugi/pull/107) ([hakobera](https://github.com/hakobera))
|
17
|
+
|
18
|
+
## [v0.6.1](https://github.com/tumugi/tumugi/tree/v0.6.1) (2016-07-10)
|
19
|
+
[Full Changelog](https://github.com/tumugi/tumugi/compare/v0.6.0...v0.6.1)
|
5
20
|
|
6
21
|
**Merged pull requests:**
|
7
22
|
|
23
|
+
- Prepare release for 0.6.1 [\#103](https://github.com/tumugi/tumugi/pull/103) ([hakobera](https://github.com/hakobera))
|
8
24
|
- Suppress unusable info log [\#102](https://github.com/tumugi/tumugi/pull/102) ([hakobera](https://github.com/hakobera))
|
9
25
|
|
10
26
|
## [v0.6.0](https://github.com/tumugi/tumugi/tree/v0.6.0) (2016-07-09)
|
data/lib/tumugi.rb
CHANGED
data/lib/tumugi/cli.rb
CHANGED
@@ -9,7 +9,7 @@ module Tumugi
|
|
9
9
|
class << self
|
10
10
|
def common_options
|
11
11
|
option :file, aliases: '-f', desc: 'Workflow file name', required: true
|
12
|
-
option :config, aliases: '-c', desc: 'Configuration file name'
|
12
|
+
option :config, aliases: '-c', desc: 'Configuration file name'
|
13
13
|
option :params, aliases: '-p', type: :hash, desc: 'Task parameters'
|
14
14
|
option :quiet, type: :boolean, desc: 'Suppress log', default: false
|
15
15
|
option :verbose, type: :boolean, desc: 'Show verbose log', default: false
|
@@ -53,39 +53,45 @@ module Tumugi
|
|
53
53
|
private
|
54
54
|
|
55
55
|
def execute(command, task, options)
|
56
|
+
args = { task: task, options: options }
|
56
57
|
success = Tumugi.workflow.execute(command, task, options)
|
57
58
|
unless success
|
58
|
-
raise Thor::Error, "execute finished, but
|
59
|
+
raise Thor::Error, "execute finished, but failed"
|
59
60
|
end
|
60
|
-
logger.info "status: success, command: #{command},
|
61
|
+
logger.info "status: success, command: #{command}, args: #{args}"
|
61
62
|
rescue => e
|
62
|
-
|
63
|
-
logger.error e.message
|
64
|
-
if options[:verbose]
|
65
|
-
e.backtrace.each { |line| logger.debug line }
|
66
|
-
else
|
67
|
-
logger.error "If you want to know more detail, run with '--verbose' option"
|
68
|
-
end
|
69
|
-
logger.error "status: failed, command: #{command}, task: #{task}, options: #{options}"
|
70
|
-
raise Thor::Error.new("tumugi #{command} failed, please check log")
|
63
|
+
handle_error(command, e, args)
|
71
64
|
end
|
72
65
|
|
73
66
|
def generate_plugin(name, options)
|
67
|
+
args = { name: name, options: options }
|
74
68
|
Tumugi::Command::New.new.execute(name, options)
|
75
|
-
logger.info "status: success, command: new,
|
69
|
+
logger.info "status: success, command: new, args: #{args}"
|
76
70
|
rescue => e
|
71
|
+
handle_error("new", e, args)
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def handle_error(command, e, args)
|
77
|
+
logger.error "#{command} command failed"
|
77
78
|
logger.error e.message
|
79
|
+
reason = e
|
80
|
+
if e.is_a?(Tumugi::TumugiError) && !e.reason.nil?
|
81
|
+
reason = e.reason
|
82
|
+
logger.error reason.message
|
83
|
+
end
|
78
84
|
if options[:verbose]
|
79
|
-
|
85
|
+
logger.error { reason.backtrace.join("\n") }
|
80
86
|
else
|
81
87
|
logger.error "If you want to know more detail, run with '--verbose' option"
|
82
88
|
end
|
83
|
-
logger.error "status: failed, command:
|
89
|
+
logger.error "status: failed, command: #{command}, args: #{args}"
|
84
90
|
raise Thor::Error.new("tumugi new failed, please check log")
|
85
91
|
end
|
86
92
|
|
87
93
|
def logger
|
88
|
-
Tumugi::
|
94
|
+
@logger ||= Tumugi::ScopedLogger.new("tumugi-main")
|
89
95
|
end
|
90
96
|
end
|
91
97
|
end
|
data/lib/tumugi/command/new.rb
CHANGED
data/lib/tumugi/command/run.rb
CHANGED
@@ -6,7 +6,7 @@ module Tumugi
|
|
6
6
|
class Run
|
7
7
|
def execute(dag, options={})
|
8
8
|
worker_num = options[:workers] || Tumugi.config.workers
|
9
|
-
executor = Tumugi::Executor::LocalExecutor.new(dag,
|
9
|
+
executor = Tumugi::Executor::LocalExecutor.new(dag, worker_num: worker_num)
|
10
10
|
result = start(executor)
|
11
11
|
show_result_report(dag)
|
12
12
|
result
|
@@ -15,9 +15,9 @@ module Tumugi
|
|
15
15
|
private
|
16
16
|
|
17
17
|
def start(executor)
|
18
|
-
logger.info "
|
18
|
+
logger.info "workflow_start: #{Tumugi.workflow.id}"
|
19
19
|
result = executor.execute
|
20
|
-
logger.info "
|
20
|
+
logger.info "workflow_end: #{Tumugi.workflow.id}"
|
21
21
|
result
|
22
22
|
end
|
23
23
|
|
@@ -28,7 +28,7 @@ module Tumugi
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def logger
|
31
|
-
Tumugi::
|
31
|
+
@logger ||= Tumugi::ScopedLogger.new("tumugi-run")
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
data/lib/tumugi/command/show.rb
CHANGED
data/lib/tumugi/config.rb
CHANGED
@@ -11,7 +11,7 @@ module Tumugi
|
|
11
11
|
|
12
12
|
def self.register_section(name, *args)
|
13
13
|
@@sections[name] = Struct.new(camelize(name), *args)
|
14
|
-
logger.
|
14
|
+
logger.info { "registered config section '#{name}' with '#{args}'" }
|
15
15
|
end
|
16
16
|
|
17
17
|
def self.camelize(term)
|
@@ -22,7 +22,7 @@ module Tumugi
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def self.logger
|
25
|
-
Tumugi::
|
25
|
+
@logger ||= Tumugi::ScopedLogger.new("tumugi-config")
|
26
26
|
end
|
27
27
|
|
28
28
|
def initialize
|
@@ -7,10 +7,9 @@ require 'tumugi/error'
|
|
7
7
|
module Tumugi
|
8
8
|
module Executor
|
9
9
|
class LocalExecutor
|
10
|
-
def initialize(dag,
|
10
|
+
def initialize(dag, worker_num: 1)
|
11
11
|
@dag = dag
|
12
12
|
@main_task = dag.tsort.last
|
13
|
-
@logger = logger || Tumugi::Logger.instance
|
14
13
|
@options = { worker_num: worker_num }
|
15
14
|
@mutex = Mutex.new
|
16
15
|
end
|
@@ -28,17 +27,17 @@ module Tumugi
|
|
28
27
|
|
29
28
|
Concurrent::Future.execute(executor: pool) do
|
30
29
|
if !task.runnable?(Time.now)
|
31
|
-
|
30
|
+
logger.trace { "task_cannot_run: #{task.id}" }
|
32
31
|
enqueue_task(task)
|
33
32
|
else
|
34
33
|
begin
|
35
|
-
info "
|
34
|
+
logger.info { "task_start: #{task.id}" }
|
36
35
|
task.trigger!(:start)
|
37
36
|
MuchTimeout.optional_timeout(task_timeout(task), Tumugi::TimeoutError) do
|
38
37
|
task.run
|
39
38
|
end
|
40
39
|
task.trigger!(:complete)
|
41
|
-
info "#{task.state}: #{task.id}"
|
40
|
+
logger.info { "task_#{task.state}: #{task.id}" }
|
42
41
|
rescue => e
|
43
42
|
handle_error(task, e)
|
44
43
|
end
|
@@ -69,7 +68,7 @@ module Tumugi
|
|
69
68
|
def dequeue_task
|
70
69
|
loop do
|
71
70
|
task = @mutex.synchronize {
|
72
|
-
|
71
|
+
logger.trace { "task_queue_dump: #{@queue.map(&:id)}" } unless @queue.empty?
|
73
72
|
@queue.shift
|
74
73
|
}
|
75
74
|
|
@@ -80,14 +79,14 @@ module Tumugi
|
|
80
79
|
sleep(0.1)
|
81
80
|
end
|
82
81
|
else
|
83
|
-
|
82
|
+
logger.trace { "task_queue_dequeue: #{task.id}" }
|
84
83
|
|
85
84
|
if task.requires_failed?
|
86
85
|
task.trigger!(:requires_fail)
|
87
|
-
info "#{task.state}: #{task.id} has failed requires task"
|
86
|
+
logger.info { "task_#{task.state}: #{task.id} has failed requires task" }
|
88
87
|
elsif task.completed?
|
89
88
|
task.trigger!(:skip)
|
90
|
-
info "#{task.state}: #{task.id} is already completed"
|
89
|
+
logger.info { "task_#{task.state}: #{task.id} is already completed" }
|
91
90
|
else
|
92
91
|
break task
|
93
92
|
end
|
@@ -96,30 +95,26 @@ module Tumugi
|
|
96
95
|
end
|
97
96
|
|
98
97
|
def enqueue_task(task)
|
99
|
-
|
98
|
+
logger.trace { "task_queue_enqueue: #{task.id}" }
|
100
99
|
@mutex.synchronize { @queue.push(task) }
|
101
100
|
end
|
102
101
|
|
103
102
|
def handle_error(task, err)
|
104
103
|
if task.retry
|
105
104
|
task.trigger!(:pend)
|
106
|
-
|
105
|
+
logger.error { "#{err.class}: '#{err.message}' - #{task.tries} tries and wait #{task.retry_interval} seconds until the next try." }
|
107
106
|
enqueue_task(task)
|
108
107
|
else
|
109
108
|
task.trigger!(:fail)
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
@logger.debug { err.backtrace.join("\n") }
|
109
|
+
logger.error { "#{err.class}: '#{err.message}' - #{task.tries} tries and reached max retry count, so task #{task.id} failed." }
|
110
|
+
logger.error { "#{err.message}" }
|
111
|
+
logger.error { err.backtrace.join("\n") }
|
114
112
|
end
|
113
|
+
logger.info { "task_#{task.state}: error handeling done for #{task.id}" }
|
115
114
|
end
|
116
115
|
|
117
|
-
def
|
118
|
-
@logger
|
119
|
-
end
|
120
|
-
|
121
|
-
def debug(&block)
|
122
|
-
@logger.debug { "#{block.call}, thread: #{Thread.current.object_id}" }
|
116
|
+
def logger
|
117
|
+
@logger ||= Tumugi::ScopedLogger.new("tumugi-executor")
|
123
118
|
end
|
124
119
|
end
|
125
120
|
end
|
@@ -7,7 +7,9 @@ module Tumugi
|
|
7
7
|
class Logger
|
8
8
|
include Singleton
|
9
9
|
extend Forwardable
|
10
|
-
def_delegators :@logger,
|
10
|
+
def_delegators :@logger, :debug, :debug?, :error, :error?,
|
11
|
+
:fatal, :fatal?, :info, :info?,
|
12
|
+
:warn, :warn?, :level
|
11
13
|
attr_accessor :workflow_id
|
12
14
|
|
13
15
|
def initialize
|
@@ -35,21 +37,16 @@ module Tumugi
|
|
35
37
|
private
|
36
38
|
|
37
39
|
def text_formatter
|
38
|
-
Proc.new { |
|
39
|
-
|
40
|
-
"#{datetime} #{severity} [#{workflow_id}] #{msg}\n"
|
41
|
-
else
|
42
|
-
"#{datetime} #{severity} #{msg}\n"
|
43
|
-
end
|
40
|
+
Proc.new { |level, datetime, program_name, msg|
|
41
|
+
"#{datetime} [#{level}]#{' (' + program_name + ')' unless program_name.nil?} #{msg}\n"
|
44
42
|
}
|
45
43
|
end
|
46
44
|
|
47
45
|
def json_formatter
|
48
|
-
Proc.new { |
|
49
|
-
hash = { time: datetime,
|
50
|
-
|
51
|
-
|
52
|
-
end
|
46
|
+
Proc.new { |level, datetime, program_name, msg|
|
47
|
+
hash = { time: datetime, level: level, message: msg }
|
48
|
+
hash[:program_name] = program_name unless program_name.nil?
|
49
|
+
hash[:workflow] = workflow_id unless workflow_id.nil?
|
53
50
|
"#{JSON.generate(hash)}\n"
|
54
51
|
}
|
55
52
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'tumugi/logger/logger'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
module Tumugi
|
5
|
+
class ScopedLogger
|
6
|
+
extend Forwardable
|
7
|
+
def_delegators :@logger, :init, :verbose!, :quiet!, :workflow_id, :workflow_id=,
|
8
|
+
:debug?, :error?, :fatal?, :info?, :warn?, :level
|
9
|
+
|
10
|
+
def initialize(scope)
|
11
|
+
@scope = scope
|
12
|
+
@logger = Tumugi::Logger.instance
|
13
|
+
end
|
14
|
+
|
15
|
+
[:debug, :error, :fatal, :info, :warn].each do |level|
|
16
|
+
class_eval "def #{level}(msg=nil, &block); log(:#{level}, msg, &block) end", __FILE__, __LINE__
|
17
|
+
end
|
18
|
+
|
19
|
+
def trace(msg=nil, &block)
|
20
|
+
if ENV.key?("TUMUGI_DEBUG")
|
21
|
+
log(:debug, msg, &block)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def log(level, msg=nil, &block)
|
28
|
+
if block_given?
|
29
|
+
@logger.send(level, progname, &block)
|
30
|
+
else
|
31
|
+
@logger.send(level, progname) { msg }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def progname
|
36
|
+
if @scope.is_a?(Proc)
|
37
|
+
@scope.call
|
38
|
+
else
|
39
|
+
@scope.to_s
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/tumugi/target.rb
CHANGED
data/lib/tumugi/task.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'tumugi/logger/scoped_logger'
|
1
2
|
require 'tumugi/mixin/listable'
|
2
3
|
require 'tumugi/mixin/task_helper'
|
3
4
|
require 'tumugi/mixin/parameterizable'
|
@@ -50,7 +51,7 @@ module Tumugi
|
|
50
51
|
end
|
51
52
|
|
52
53
|
def logger
|
53
|
-
@logger ||= Tumugi::
|
54
|
+
@logger ||= Tumugi::ScopedLogger.new(->{"Thread-#{Thread.list.index {|t| t == Thread.current}}: #{id}"})
|
54
55
|
end
|
55
56
|
|
56
57
|
def log(msg)
|
data/lib/tumugi/version.rb
CHANGED
data/lib/tumugi/workflow.rb
CHANGED
@@ -13,6 +13,8 @@ module Tumugi
|
|
13
13
|
attr_reader :id
|
14
14
|
attr_accessor :params
|
15
15
|
|
16
|
+
DEFAULT_CONFIG_FILE = "tumugi_config.rb"
|
17
|
+
|
16
18
|
def initialize
|
17
19
|
@id = SecureRandom.uuid
|
18
20
|
@tasks = {}
|
@@ -42,13 +44,13 @@ module Tumugi
|
|
42
44
|
|
43
45
|
def load_workflow_file(file)
|
44
46
|
unless File.exist?(file)
|
45
|
-
raise Tumugi::TumugiError, "Workflow file '#{file}' not exist
|
47
|
+
raise Tumugi::TumugiError, "Workflow file '#{file}' does not exist"
|
46
48
|
end
|
47
49
|
|
48
50
|
begin
|
49
51
|
logger.info "Load workflow from #{file}"
|
50
52
|
load(file, true)
|
51
|
-
rescue
|
53
|
+
rescue Exception => e
|
52
54
|
raise Tumugi::TumugiError.new("Workflow file load error: #{file}", e)
|
53
55
|
end
|
54
56
|
end
|
@@ -67,7 +69,7 @@ module Tumugi
|
|
67
69
|
end
|
68
70
|
|
69
71
|
def logger
|
70
|
-
@logger ||= Tumugi::
|
72
|
+
@logger ||= Tumugi::ScopedLogger.new("tumugi-workflow")
|
71
73
|
end
|
72
74
|
|
73
75
|
def setup_logger(command, options)
|
@@ -84,12 +86,23 @@ module Tumugi
|
|
84
86
|
|
85
87
|
def load_config(options)
|
86
88
|
config_file = options[:config]
|
87
|
-
|
89
|
+
|
90
|
+
if config_file && !File.exist?(config_file)
|
91
|
+
raise Tumugi::TumugiError, "Config file '#{config_file}' does not exist"
|
92
|
+
end
|
93
|
+
|
94
|
+
if !config_file && File.exist?(DEFAULT_CONFIG_FILE)
|
95
|
+
config_file = DEFAULT_CONFIG_FILE
|
96
|
+
end
|
97
|
+
|
98
|
+
if config_file && File.exist?(config_file)
|
88
99
|
logger.info "Load config from #{config_file}"
|
89
|
-
|
100
|
+
begin
|
101
|
+
load(config_file)
|
102
|
+
rescue Exception => e
|
103
|
+
raise Tumugi::TumugiError.new("Config file load error: #{config_file}", e)
|
104
|
+
end
|
90
105
|
end
|
91
|
-
rescue LoadError => e
|
92
|
-
raise Tumugi::TumugiError.new("Config file load error: #{config_file}", e)
|
93
106
|
end
|
94
107
|
|
95
108
|
def set_params(options)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tumugi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kazuyuki Honda
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -219,7 +219,8 @@ files:
|
|
219
219
|
- lib/tumugi/error.rb
|
220
220
|
- lib/tumugi/executor/local_executor.rb
|
221
221
|
- lib/tumugi/file_system.rb
|
222
|
-
- lib/tumugi/logger.rb
|
222
|
+
- lib/tumugi/logger/logger.rb
|
223
|
+
- lib/tumugi/logger/scoped_logger.rb
|
223
224
|
- lib/tumugi/mixin/listable.rb
|
224
225
|
- lib/tumugi/mixin/parameterizable.rb
|
225
226
|
- lib/tumugi/mixin/task_helper.rb
|