norikra 0.0.4-java → 0.0.5-java

Sign up to get free protection for your applications and to get access to all the features.
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- jruby-1.7.3
1
+ jruby-1.7.4
data/README.md CHANGED
@@ -52,12 +52,8 @@ https://github.com/tagomoris/norikra-client
52
52
 
53
53
  For example, think about event streams related with one web service (ex: 'www'). At first, define `target` with mandantory fields (in other words, minimal fields set for variations of 'www' events).
54
54
 
55
- norikra-client table add www path:string status:integer referer:string agent:string userid:integer
56
- norikra-client table list
57
-
58
- Fields not defined in 'table add' are automatically defined when events arrived at Norikra. You should not worry about it, but optional fields are defined as 'string' field. If you want to define as 'long' or 'double' or 'boolean', define field for each.
59
-
60
- norikra-client field define www age:integer
55
+ norikra-client target add www path:string status:integer referer:string agent:string userid:integer
56
+ norikra-client target list
61
57
 
62
58
  You can register queries when you want.
63
59
 
@@ -96,7 +92,6 @@ TBD
96
92
 
97
93
  ## TODO
98
94
 
99
- * logging
100
95
  * daemonize
101
96
  * performance parameters
102
97
  * query unregister
data/lib/norikra/cli.rb CHANGED
@@ -7,18 +7,43 @@ module Norikra
7
7
  option :host, :type => :string, :default => '0.0.0.0', :aliases => "-H", :desc => 'host address that server listen [0.0.0.0]'
8
8
  option :port, :type => :numeric, :default => 26571, :aliases => "-P", :desc => 'port that server uses [26571]'
9
9
  # option :config, :type => :string, :default => nil, :aliases => "-c", :desc => 'configuration file to define target/query [none]'
10
- # option :daemonize, :type => :boolean, :default => false, :aliases => "-d", :desc => 'daemonize Norikra server [false]'
11
- # option :pidfile, :type => :string, :default => '/var/run/norikra.pid', :aliases => "-p", :desc => "pidfile path when daemonized [/var/run/norikra.pid]"
12
- # option :logfile, :type => :string, :default => '/var/log/norikra.log', :aliases => "-l", :desc => "logfile path when daemonized [/var/log/norikra.log]"
10
+
11
+ option :daemonize, :type => :boolean, :default => false, :aliases => "-d", \
12
+ :desc => 'daemonize Norikra server [false (foreground)]'
13
+ option :pidfile, :type => :string, :default => '/var/run/norikra.pid', :aliases => "-p", \
14
+ :desc => "pidfile path when daemonized [/var/run/norikra.pid]"
15
+
16
+ option :logdir, :type => :string, :default => nil, :aliases => "-l", \
17
+ :desc => "directory path of logfiles when daemonized [nil (console)]"
18
+ option :'log-filesize', :type => :string, :default => '10MB'
19
+ option :'log-backups' , :type => :numeric, :default => 10
20
+
21
+ option :'more-quiet', :type => :boolean, :default => false, :desc => 'set loglevel as ERROR'
22
+ option :quiet, :type => :boolean, :default => false, :aliases => "-q", :desc => 'set loglevel as WARN'
23
+ option :verbose, :type => :boolean, :default => false, :aliases => "-v", :desc => 'set loglevel as DEBUG'
24
+ option :'more-verbose', :type => :boolean, :default => false, :desc => 'set loglevel as TRACE'
13
25
 
14
26
  #TODO: configuration file to init
15
- #TODO: daemonize
16
- # TODO: pidcheck
17
- # TODO: open logfile & write
18
- # TODO: logfile reopen
19
27
  def start
20
- server = Norikra::Server.new(options[:host], options[:port])
28
+ conf = {}
29
+
30
+ #TODO: daemonize
31
+ raise NotImplementedError if options[:daemonize]
32
+ #TODO: pidcheck if daemonize
33
+
34
+ conf[:loglevel] = case
35
+ when options[:'more-verbose'] then 'TRACE'
36
+ when options[:verbose] then 'DEBUG'
37
+ when options[:quiet] then 'WARN'
38
+ when options[:'more-quiet'] then 'ERROR'
39
+ else nil # for default (assumed as 'INFO')
40
+ end
41
+ conf[:logdir] = options[:logdir]
42
+ conf[:logfilesize] = options[:'log-filesize']
43
+ conf[:logbackups] = options[:'log-backups']
44
+ server = Norikra::Server.new( options[:host], options[:port], conf )
21
45
  server.run
46
+ server.shutdown
22
47
  end
23
48
  end
24
49
  end
@@ -1,4 +1,8 @@
1
1
  require 'java'
2
+
3
+ require 'norikra/logger'
4
+ include Norikra::Log
5
+
2
6
  require 'esper-4.9.0.jar'
3
7
  require 'esper/lib/commons-logging-1.1.1.jar'
4
8
  require 'esper/lib/antlr-runtime-3.2.jar'
@@ -37,11 +41,13 @@ module Norikra
37
41
  end
38
42
 
39
43
  def open(target, fields=nil)
40
- return if @targets.include?(target)
44
+ info "opening target", :target => target, :fields => fields
45
+ return false if @targets.include?(target)
41
46
  open_target(target, fields)
42
47
  end
43
48
 
44
49
  def close(target)
50
+ info "closing target", :target => target
45
51
  #TODO: write
46
52
  raise NotImplementedError
47
53
  end
@@ -51,6 +57,7 @@ module Norikra
51
57
  end
52
58
 
53
59
  def register(query)
60
+ info "registering query", :name => query.name, :targets => query.targets, :expression => query.expression
54
61
  unless @targets.include?(query.targets.first)
55
62
  open(query.targets.first) # open as lazy defined target
56
63
  end
@@ -58,19 +65,30 @@ module Norikra
58
65
  end
59
66
 
60
67
  def deregister(query_name)
68
+ info "de-registering query", :name => query_name
61
69
  #TODO: write
62
70
  raise NotImplementedError
63
71
  end
64
72
 
65
73
  def send(target, events)
66
- #TODO: trace log
67
- #p events
68
- return unless @targets.include?(target) # discard events for target not registered
74
+ trace "send messages", :target => target, :events => events
75
+ unless @targets.include?(target) # discard events for target not registered
76
+ trace "messages skipped for non-opened target", :target => target
77
+ return
78
+ end
69
79
  return if events.size < 1
70
80
 
71
81
  if @typedef_manager.lazy?(target)
82
+ info "opening lazy target", :target => target
83
+ debug "generating base fieldset from event", :target => target, :event => events.first
84
+
72
85
  base_fieldset = @typedef_manager.generate_base_fieldset(target, events.first)
86
+
87
+ debug "registering base fieldset", :target => target, :base => base_fieldset
88
+
73
89
  register_base_fieldset(target, base_fieldset)
90
+
91
+ info "target successfully opened with fieldset", :target => target, :base => base_fieldset
74
92
  end
75
93
 
76
94
  registered_data_fieldset = @registered_fieldsets[target][:data]
@@ -80,10 +98,14 @@ module Norikra
80
98
 
81
99
  unless registered_data_fieldset[fieldset.summary]
82
100
  # register waiting queries including this fieldset, and this fieldset itself
101
+ debug "registering unknown fieldset", :target => target, :fieldset => fieldset
102
+
83
103
  register_fieldset(target, fieldset)
104
+
105
+ debug "successfully registered"
84
106
  end
85
- #TODO: trace log
86
- #p "sendEvent eventType:#{fieldset.event_type_name}, event:#{event.inspect}"
107
+
108
+ trace "calling sendEvent", :target => target, :fieldset => fieldset, :event_type_name => fieldset.event_type_name, :event => event
87
109
  @runtime.sendEvent(@typedef_manager.format(target, event).to_java, fieldset.event_type_name)
88
110
  end
89
111
  nil
@@ -117,7 +139,7 @@ module Norikra
117
139
  def open_target(target, fields)
118
140
  # from open
119
141
  @mutex.synchronize do
120
- return if @targets.include?(target)
142
+ return false if @targets.include?(target)
121
143
  @typedef_manager.add_target(target, fields)
122
144
  @registered_fieldsets[target] = {:base => {}, :query => {}, :data => {}}
123
145
 
@@ -130,17 +152,17 @@ module Norikra
130
152
 
131
153
  @targets.push(target)
132
154
  end
155
+ true
133
156
  end
134
157
 
135
158
  def register_base_fieldset(target, fieldset)
136
159
  # for lazy target, with generated fieldset from sent events.first
137
160
  @mutex.synchronize do
138
- return unless @typedef_manager.lazy?(target)
139
-
140
- @typedef_manager.bind_fieldset(target, :base, fieldset)
141
- register_fieldset_actually(target, fieldset, :base)
161
+ return false unless @typedef_manager.lazy?(target)
142
162
 
143
163
  @typedef_manager.activate(target, fieldset)
164
+ # @typedef_manager.bind_fieldset(target, :base, fieldset)
165
+ register_fieldset_actually(target, fieldset, :base)
144
166
  end
145
167
  nil
146
168
  end
@@ -160,7 +182,8 @@ module Norikra
160
182
 
161
183
  # replace registered data fieldsets with new fieldset inherits this query fieldset
162
184
  @typedef_manager.supersets(target, query_fieldset).each do |set|
163
- rebound = set.rebind
185
+ rebound = set.rebind(true) # update event_type_name with new inheritations
186
+
164
187
  register_fieldset_actually(target, rebound, :data, true) # replacing
165
188
  @typedef_manager.replace_fieldset(target, set, rebound)
166
189
  remove_fieldset_actually(target, set, :data)
@@ -0,0 +1,219 @@
1
+ require 'java'
2
+ require 'esper/lib/commons-logging-1.1.1.jar'
3
+
4
+ require 'monitor'
5
+
6
+ #### To use this logger
7
+ # require 'norikra/logger'
8
+ # include Norikra::Log
9
+ # # and
10
+ ## info "message..."
11
+ ## debug "debugging...", :args => parameters, :status => 'status'
12
+
13
+ module Norikra
14
+ # 2013-06-21 15:49:30 +0900 [INFO](main) : this is error log, status:'404', message:'content not found'
15
+
16
+ # devmode
17
+ # 2013-06-21 15:49:30 +0900 [INFO](main) /path/of/logger.rb:27(method): this is error log, status:'404', message:'content not found'
18
+
19
+ # 2013-06-21 15:49:30 +0900 [info](main) MESSAGE
20
+ LOG_LOG4J_FORMAT = '%d{yyyy-MM-dd HH:mm:ss Z} [%p] %m%n'
21
+ LOG_FORMAT = '%s: %s%s'
22
+
23
+ LOG_LOG4J_BUILTIN_FORMAT = '%d{yyyy-MM-dd HH:mm:ss Z} [%p](%t)<%c> %m%n'
24
+
25
+ LOGFILE_DEFAULT_MAX_SIZE = '10MB'
26
+ LOGFILE_DEFAULT_MAX_BACKUP_INDEX = 10
27
+
28
+ LOG_LEVELS = ['TRACE','DEBUG','INFO','WARN','ERROR','FATAL'].freeze
29
+ LOG_LEVEL_DEFAULT = 'INFO'
30
+
31
+ LEVEL_TRACE = LOG_LEVELS.index('TRACE')
32
+ LEVEL_DEBUG = LOG_LEVELS.index('DEBUG')
33
+ LEVEL_INFO = LOG_LEVELS.index('INFO')
34
+ LEVEL_WARN = LOG_LEVELS.index('WARN')
35
+ LEVEL_ERROR = LOG_LEVELS.index('ERROR')
36
+
37
+ module Log
38
+ @@logger = nil
39
+
40
+ @@level = nil
41
+ @@levelnum = nil
42
+ @@devmode = false
43
+
44
+ @@mon = Monitor.new
45
+
46
+ def self.init(level, logdir, opts, devmode=false)
47
+ level ||= LOG_LEVEL_DEFAULT
48
+ # logdir: nil => ConsoleAppender
49
+ # else => RollingFileAppender (output: directory path)
50
+ # http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/RollingFileAppender.html
51
+
52
+ @@level = level.upcase
53
+ raise ArgumentError, "unknown log level: #{@@level}" unless LOG_LEVELS.include?(@@level)
54
+ @@levelnum = LOG_LEVELS.index(@@level)
55
+
56
+ p = java.util.Properties.new
57
+ p.setProperty('log4j.appender.default.layout', 'org.apache.log4j.PatternLayout')
58
+ p.setProperty('log4j.appender.default.layout.ConversionPattern', LOG_LOG4J_FORMAT)
59
+
60
+ # for esper epl & mizuno jetty
61
+ esper_log_limit = 'WARN'
62
+ p.setProperty('log4j.logger.com.espertech.esper', "#{esper_log_limit}, builtin")
63
+ mizuno_log_limit = 'WARN'
64
+ p.setProperty('log4j.logger.ruby', "#{mizuno_log_limit}, builtin")
65
+ p.setProperty('log4j.logger.org.eclipse.jetty', "#{mizuno_log_limit}, builtin")
66
+
67
+ p.setProperty('log4j.appender.builtin.layout', 'org.apache.log4j.PatternLayout')
68
+ p.setProperty('log4j.appender.builtin.layout.ConversionPattern', LOG_LOG4J_BUILTIN_FORMAT)
69
+
70
+ if logdir.nil?
71
+ p.setProperty('log4j.appender.default', 'org.apache.log4j.ConsoleAppender')
72
+ p.setProperty('log4j.appender.builtin', 'org.apache.log4j.ConsoleAppender')
73
+ else
74
+ # DailyRollingFileAppender ?
75
+ # http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/DailyRollingFileAppender.html
76
+ norikra_log = File.join(logdir, 'norikra.log')
77
+ p.setProperty('log4j.appender.default', 'org.apache.log4j.RollingFileAppender')
78
+ p.setProperty('log4j.appender.default.File', norikra_log)
79
+ p.setProperty('log4j.appender.default.MaxFileSize', opts[:filesize] || LOGFILE_DEFAULT_MAX_SIZE)
80
+ p.setProperty('log4j.appender.default.MaxBackupIndex', opts[:backups].to_s || LOGFILE_DEFAULT_MAX_BACKUP_INDEX.to_s)
81
+
82
+ builtin_log = File.join(logdir, 'builtin.log')
83
+ p.setProperty('log4j.appender.builtin', 'org.apache.log4j.RollingFileAppender')
84
+ p.setProperty('log4j.appender.builtin.File', builtin_log)
85
+ p.setProperty('log4j.appender.builtin.MaxFileSize', opts[:filesize] || LOGFILE_DEFAULT_MAX_SIZE)
86
+ p.setProperty('log4j.appender.builtin.MaxBackupIndex', opts[:backups].to_s || LOGFILE_DEFAULT_MAX_BACKUP_INDEX.to_s)
87
+ end
88
+
89
+ p.setProperty('log4j.rootLogger', "#{@@level},default")
90
+ org.apache.log4j.PropertyConfigurator.configure(p)
91
+
92
+ @@logger = Logger.new('norikra.log')
93
+
94
+ @@devmode = devmode
95
+ end
96
+
97
+ def self.swap(logger) # for tests
98
+ @@mon.synchronize do
99
+ original,@@logger = @@logger, logger
100
+ yield
101
+ @@logger = original
102
+ end
103
+ end
104
+
105
+ def trace(message, data=nil)
106
+ return if LEVEL_TRACE < @@levelnum
107
+ from = @@devmode ? caller_locations(1,1) : nil
108
+ @@logger.trace(message, data, from)
109
+ end
110
+
111
+ def debug(message, data=nil)
112
+ return if LEVEL_DEBUG < @@levelnum
113
+ from = @@devmode ? caller_locations(1,1) : nil
114
+ @@logger.debug(message, data, from)
115
+ end
116
+
117
+ def info(message, data=nil)
118
+ return if LEVEL_INFO < @@levelnum
119
+ from = @@devmode ? caller_locations(1,1) : nil
120
+ @@logger.info(message, data, from)
121
+ end
122
+
123
+ def warn(message, data=nil)
124
+ return if LEVEL_WARN < @@levelnum
125
+ from = @@devmode ? caller_locations(1,1) : nil
126
+ @@logger.warn(message, data, from)
127
+ end
128
+
129
+ def error(message, data=nil)
130
+ return if LEVEL_ERROR < @@levelnum
131
+ from = @@devmode ? caller_locations(1,1) : nil
132
+ @@logger.error(message, data, from)
133
+ end
134
+
135
+ def fatal(message, data=nil)
136
+ from = @@devmode ? caller_locations(1,1) : nil
137
+ @@logger.fatal(message, data, from)
138
+ end
139
+ end
140
+
141
+ class Logger
142
+ def initialize(name)
143
+ @log4j = org.apache.commons.logging.LogFactory.getLog(name)
144
+ end
145
+
146
+ def trace(message, data=nil, from=nil)
147
+ @log4j.trace(format(from, message, data))
148
+ end
149
+
150
+ def debug(message, data=nil, from=nil)
151
+ @log4j.debug(format(from, message, data))
152
+ end
153
+
154
+ def info(message, data=nil, from=nil)
155
+ @log4j.info(format(from, message, data))
156
+ end
157
+
158
+ def warn(message, data=nil, from=nil)
159
+ @log4j.warn(format(from, message, data))
160
+ end
161
+
162
+ def error(message, data=nil, from=nil)
163
+ @log4j.error(format(from, message, data))
164
+ end
165
+
166
+ def fatal(message, data=nil, from=nil)
167
+ @log4j.fatal(format(from, message, data))
168
+ end
169
+
170
+ def format_location(locations)
171
+ return '' if locations.nil?
172
+ c = locations.first
173
+ "#{c.path}:#{c.lineno}(#{c.label})"
174
+ end
175
+
176
+ def format_data(data=nil)
177
+ return '' if data.nil?
178
+
179
+ #, status:404, message:'content not found'
180
+ if data.is_a?(Proc)
181
+ ', ' + format_data(data.call)
182
+ elsif data.is_a?(Hash)
183
+ ', ' + data.map{|k,v| "#{k}:#{v.inspect}"}.join(', ')
184
+ else
185
+ ', ' + data.inspect
186
+ end
187
+ end
188
+
189
+ def format(from, message, data)
190
+ # LOG_FORMAT = '%s: %s%s'
191
+ LOG_FORMAT % [format_location(from), message, format_data(data)]
192
+ end
193
+ end
194
+
195
+ class DummyLogger < Logger # for tests
196
+ # LOG_LOG4J_FORMAT = '%d{yyyy-MM-dd HH:mm:ss Z} [%p] %m%n'
197
+ # LOG_FORMAT = '%s: %s%s'
198
+ FORMAT_SIMULATED = "%s [%s] %s\n"
199
+ FORMAT_SIMULATED_TIME = '%Y-%m-%d %H:%M:%S %z'
200
+ attr_accessor :logs, :output
201
+ def initialize
202
+ @logs = { :TRACE => [], :DEBUG => [], :INFO => [], :WARN => [], :ERROR => [], :FATAL => [] }
203
+ @output = []
204
+ end
205
+ def log(level, message, data, from)
206
+ @logs[level].push({:message => message, :data => data, :from => from})
207
+ formatted = sprintf(FORMAT_SIMULATED, Time.now.strftime(FORMAT_SIMULATED_TIME), level.to_s, format(from, message, data))
208
+ @output.push(formatted)
209
+ end
210
+ def trace(m,d,f); self.log(:TRACE,m,d,f); end
211
+ def debug(m,d,f); self.log(:DEBUG,m,d,f); end
212
+ def info(m,d,f) ; self.log(:INFO, m,d,f); end
213
+ def warn(m,d,f) ; self.log(:WARN, m,d,f); end
214
+ def error(m,d,f); self.log(:ERROR,m,d,f); end
215
+ def fatal(m,d,f); self.log(:FATAL,m,d,f); end
216
+ end
217
+ end
218
+
219
+ require_relative './logger_mizuno_patch'
@@ -0,0 +1,27 @@
1
+ require 'java'
2
+ require 'esper/lib/log4j-1.2.16.jar'
3
+ require 'mizuno/logger'
4
+
5
+ module Mizuno
6
+ class Logger
7
+ def Logger.configure(options = {})
8
+ return if @options
9
+ @options = options
10
+
11
+ ### built-in jetty log level is fixed as 'WARN' for Norikra
12
+ ### Base logging configuration.
13
+ # mizuno_log_limit = "WARN"
14
+ # config = <<-END
15
+ # log4j.logger.ruby = #{mizuno_log_limit}
16
+ # log4j.logger.org.eclipse.jetty.util.log = #{mizuno_log_limit}, ruby
17
+ # END
18
+
19
+ ### appender configuration will be done out of mizuno
20
+
21
+ # Create the default logger that gets used everywhere.
22
+ @logger = new
23
+ end
24
+ end
25
+ end
26
+
27
+
@@ -1,56 +1,99 @@
1
+ require 'norikra/logger'
2
+ include Norikra::Log
3
+
1
4
  class Norikra::RPC::Handler
2
5
  def initialize(engine)
3
6
  @engine = engine
4
7
  end
5
8
 
9
+ def logging(type, handler, *args)
10
+ if type == :manage
11
+ debug "RPC", :handler => handler.to_s, :args => args
12
+ else
13
+ trace "RPC", :handler => handler.to_s, :args => args
14
+ end
15
+
16
+ begin
17
+ yield
18
+ rescue => e
19
+ error "Exception #{e.class}: #{e.message}"
20
+ e.backtrace.each do |t|
21
+ error " " + t
22
+ end
23
+ nil
24
+ end
25
+ end
26
+
6
27
  def targets
7
- @engine.targets
28
+ logging(:show, :targets){
29
+ @engine.targets
30
+ }
8
31
  end
9
32
 
10
33
  def open(target, fields)
11
- r = @engine.open(target, fields)
12
- !!r
34
+ logging(:manage, :open, target, fields){
35
+ r = @engine.open(target, fields)
36
+ !!r
37
+ }
13
38
  end
14
39
 
15
40
  def close(target)
16
- r = @engine.close(target)
17
- !!r
41
+ logging(:manage, :close, target){
42
+ r = @engine.close(target)
43
+ !!r
44
+ }
18
45
  end
19
46
 
20
47
  def queries
21
- @engine.queries.map(&:to_hash)
48
+ logging(:show, :queries){
49
+ @engine.queries.map(&:to_hash)
50
+ }
22
51
  end
23
52
 
24
53
  def register(query_name, expression)
25
- r = @engine.register(Norikra::Query.new(:name => query_name, :expression => expression))
26
- !!r
54
+ logging(:manage, :register, query_name, expression){
55
+ r = @engine.register(Norikra::Query.new(:name => query_name, :expression => expression))
56
+ !!r
57
+ }
27
58
  end
28
59
 
29
60
  def deregister(query_name)
30
- #TODO: write!
31
- raise NotImplementedError
61
+ logging(:manage, :deregister, query_name){
62
+ #TODO: write!
63
+ raise NotImplementedError
64
+ }
32
65
  end
33
66
 
34
67
  def fields(target)
35
- @engine.typedef_manager.field_list(target)
68
+ logging(:show, :fields, target){
69
+ @engine.typedef_manager.field_list(target)
70
+ }
36
71
  end
37
72
 
38
73
  def reserve(target, fieldname, type)
39
- r = @engine.reserve(target, fieldname, type)
40
- !!r
74
+ logging(:manage, :reserve, target, fieldname, type){
75
+ r = @engine.reserve(target, fieldname, type)
76
+ !!r
77
+ }
41
78
  end
42
79
 
43
80
  def send(target, events)
44
- r = @engine.send(target, events)
45
- !!r
81
+ logging(:data, :send, target, events){
82
+ r = @engine.send(target, events)
83
+ !!r
84
+ }
46
85
  end
47
86
 
48
87
  def event(query_name)
49
- @engine.output_pool.pop(query_name)
88
+ logging(:show, :event, query_name){
89
+ @engine.output_pool.pop(query_name)
90
+ }
50
91
  end
51
92
 
52
93
  def sweep
53
- @engine.output_pool.sweep
94
+ logging(:show, :sweep){
95
+ @engine.output_pool.sweep
96
+ }
54
97
  end
55
98
 
56
99
  # post('/listen') # get all events as stream, during connection keepaliving
@@ -1,5 +1,8 @@
1
1
  require 'norikra/engine'
2
2
 
3
+ require 'norikra/logger'
4
+ include Norikra::Log
5
+
3
6
  require 'norikra/typedef_manager'
4
7
  require 'norikra/output_pool'
5
8
  require 'norikra/typedef'
@@ -13,12 +16,15 @@ module Norikra
13
16
  RPC_DEFAULT_PORT = 26571
14
17
  # 26571 = 3026 + 3014 + 2968 + 2950 + 2891 + 2896 + 2975 + 2979 + 2872
15
18
 
16
- def initialize(host=RPC_DEFAULT_HOST, port=RPC_DEFAULT_PORT, configuration={})
17
- #TODO: initial configuration
18
- @typedef_manager = Norikra::TypedefManager.new
19
+ attr_accessor :running
19
20
 
21
+ def initialize(host=RPC_DEFAULT_HOST, port=RPC_DEFAULT_PORT, conf={})
22
+ #TODO: initial configuration (targets/queries)
23
+ @typedef_manager = Norikra::TypedefManager.new
20
24
  @output_pool = Norikra::OutputPool.new
21
25
 
26
+ Norikra::Log.init(conf[:loglevel], conf[:logdir], {:filesize => conf[:logfilesize], :backups => conf[:logbackups]})
27
+
22
28
  @engine = Norikra::Engine.new(@output_pool, @typedef_manager)
23
29
  @rpcserver = Norikra::RPC::HTTP.new(:engine => @engine, :port => port)
24
30
  end
@@ -26,16 +32,22 @@ module Norikra
26
32
  def run
27
33
  @engine.start
28
34
  @rpcserver.start
29
- p "Norikra server started."
30
- #TODO: main loop and signal traps
31
- #TODO: loggings
32
- sleep 50
35
+ info "Norikra server started."
36
+ @running = true
37
+
38
+ Signal.trap(:INT){ @running = false }
39
+ #TODO: more signal traps (dumps of query/fields? or other handler?)
40
+
41
+ while @running
42
+ sleep 1
43
+ end
33
44
  end
34
45
 
35
46
  def shutdown
36
- #TODO: stop order
47
+ info "Norikra server shutting down."
37
48
  @rpcserver.stop
38
49
  @engine.stop
50
+ info "Norikra server shutdown complete."
39
51
  end
40
52
  end
41
53
  end
@@ -73,7 +73,7 @@ module Norikra
73
73
  attr_accessor :summary, :fields
74
74
  attr_accessor :target, :level
75
75
 
76
- def initialize(fields, default_optional=nil)
76
+ def initialize(fields, default_optional=nil, rebounds=0)
77
77
  @fields = {}
78
78
  fields.keys.each do |key|
79
79
  data = fields[key]
@@ -90,16 +90,21 @@ module Norikra
90
90
 
91
91
  @target = nil
92
92
  @level = nil
93
+ @rebounds = rebounds
93
94
  @event_type_name = nil
94
95
  end
95
96
 
96
97
  def dup
97
98
  fields = Hash[@fields.map{|key,field| [key, {:type => field.type, :optional => field.optional}]}]
98
- self.class.new(fields)
99
+ self.class.new(fields, nil, @rebounds)
100
+ end
101
+
102
+ def self.field_names_key(data)
103
+ data.keys.sort.join(',')
99
104
  end
100
105
 
101
106
  def field_names_key
102
- @fields.keys.sort.join(',')
107
+ self.class.field_names_key(@fields)
103
108
  end
104
109
 
105
110
  def update_summary
@@ -116,7 +121,7 @@ module Norikra
116
121
 
117
122
  #TODO: have a bug?
118
123
  def ==(other)
119
- return false unless self.class != other.class
124
+ return false if self.class != other.class
120
125
  self.summary == other.summary
121
126
  end
122
127
 
@@ -136,20 +141,24 @@ module Norikra
136
141
  @event_type_name.dup
137
142
  end
138
143
 
139
- def bind(target, level)
144
+ def bind(target, level, update_type_name=false)
140
145
  @target = target
141
146
  @level = level
142
147
  prefix = case level
143
148
  when :base then 'b_'
144
149
  when :query then 'q_'
145
- else 'e_'
150
+ when :data then 'e_' # event
151
+ else
152
+ raise ArgumentError, "unknown fieldset bind level: #{level}, for target #{target}"
146
153
  end
147
- @event_type_name = prefix + Digest::MD5.hexdigest([target, level.to_s, self.object_id.to_s, @summary].join("\t"))
154
+ @rebounds += 1 if update_type_name
155
+
156
+ @event_type_name = prefix + Digest::MD5.hexdigest([target, level.to_s, @rebounds.to_s, @summary].join("\t"))
148
157
  self
149
158
  end
150
159
 
151
- def rebind
152
- self.dup.bind(@target, @level)
160
+ def rebind(update_type_name)
161
+ self.dup.bind(@target, @level, update_type_name)
153
162
  end
154
163
 
155
164
  def self.simple_guess(data, optional=true)
@@ -197,7 +206,7 @@ module Norikra
197
206
  attr_accessor :fields, :baseset, :queryfieldsets, :datafieldsets
198
207
 
199
208
  def initialize(fields=nil)
200
- if fields
209
+ if fields && !fields.empty?
201
210
  @baseset = FieldSet.new(fields, false) # all fields are required
202
211
  @fields = @baseset.fields.dup
203
212
  else
@@ -208,7 +217,7 @@ module Norikra
208
217
  @queryfieldsets = []
209
218
  @datafieldsets = []
210
219
 
211
- @set_map = {} # fieldname.sort.join(',') => data_fieldset
220
+ @set_map = {} # FieldSet.field_names_key(data_fieldset) => data_fieldset
212
221
 
213
222
  @mutex = Mutex.new
214
223
  end
@@ -223,7 +232,7 @@ module Norikra
223
232
 
224
233
  def activate(fieldset)
225
234
  @mutex.synchronize do
226
- set = fieldset.dup
235
+ set = fieldset.rebind(false) # base fieldset rebinding must not update event_type_name
227
236
  fieldset.fields.dup.each do |fieldname, field|
228
237
  set.fields[fieldname] = field.dup(false)
229
238
  end
@@ -294,15 +303,15 @@ module Norikra
294
303
  raise ArgumentError, "try to replace different field name sets"
295
304
  end
296
305
  @mutex.synchronize do
297
- @datafieldsets.push(fieldset)
298
- @set_map[fieldset.field_names_key] = fieldset
299
306
  @datafieldsets.delete(old_fieldset)
307
+ @set_map[fieldset.field_names_key] = fieldset
308
+ @datafieldsets.push(fieldset)
300
309
  end
301
310
  true
302
311
  end
303
312
 
304
313
  def refer(data)
305
- field_names_key = data.keys.sort.join(',')
314
+ field_names_key = FieldSet.field_names_key(data)
306
315
  return @set_map[field_names_key] if @set_map.has_key?(field_names_key)
307
316
 
308
317
  guessed = FieldSet.simple_guess(data)
@@ -16,7 +16,7 @@ module Norikra
16
16
  end
17
17
 
18
18
  def add_target(target, fields)
19
- # fields nil => lazy
19
+ # fields nil || [] => lazy
20
20
  # fields {'fieldname' => 'type'}
21
21
  @mutex.synchronize do
22
22
  raise RuntimeError, "target #{target} already exists" if @typedefs[target]
@@ -29,6 +29,7 @@ module Norikra
29
29
  end
30
30
 
31
31
  def activate(target, fieldset)
32
+ fieldset.bind(target, :base)
32
33
  @typedefs[target].activate(fieldset)
33
34
  end
34
35
 
@@ -1,3 +1,3 @@
1
1
  module Norikra
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
data/norikra.gemspec CHANGED
@@ -21,9 +21,9 @@ Gem::Specification.new do |spec|
21
21
 
22
22
  spec.add_runtime_dependency "mizuno", "~> 0.6"
23
23
  spec.add_runtime_dependency "rack"
24
- spec.add_runtime_dependency "msgpack-rpc-over-http-jruby", ">= 0.0.5.jruby1"
24
+ spec.add_runtime_dependency "msgpack-rpc-over-http-jruby", ">= 0.0.5"
25
25
  spec.add_runtime_dependency "thor"
26
- spec.add_runtime_dependency "norikra-client-jruby", ">= 0.0.3"
26
+ spec.add_runtime_dependency "norikra-client-jruby", ">= 0.0.4"
27
27
 
28
28
  spec.add_development_dependency "bundler", "~> 1.3"
29
29
  spec.add_development_dependency "rake"
@@ -71,8 +71,14 @@ describe Norikra::FieldSet do
71
71
  end
72
72
  end
73
73
 
74
+ describe '.field_names_key' do
75
+ it 'returns comma-separated sorted field names of argument hash' do
76
+ expect(Norikra::FieldSet.field_names_key({'x1'=>1,'y3'=>2,'xx'=>3,'xx1'=>4,'a'=>5})).to eql('a,x1,xx,xx1,y3')
77
+ end
78
+ end
79
+
74
80
  describe '#field_names_key' do
75
- it 'returns comman-separeted sorted field names' do
81
+ it 'returns comma-separeted sorted field names' do
76
82
  expect(set.field_names_key).to eql('a,x,y')
77
83
  end
78
84
  end
@@ -160,11 +166,25 @@ describe Norikra::FieldSet do
160
166
  end
161
167
 
162
168
  describe '#rebind' do
163
- it 'returns duplicated object, but these event_type_name are same' do
169
+ it 'returns duplicated object, but these event_type_name are same with false argument' do
170
+ x = set.dup
171
+ x.bind('TargetExample', :data)
172
+
173
+ y = x.rebind(false)
174
+ expect(y.summary).to eql(x.summary)
175
+ expect(y.fields.values.map(&:to_hash)).to eql(x.fields.values.map(&:to_hash))
176
+ expect(y.target).to eql(x.target)
177
+ expect(y.level).to eql(x.level)
178
+ expect(y.field_names_key).to eql(x.field_names_key)
179
+
180
+ expect(y.event_type_name).to eql(x.event_type_name)
181
+ end
182
+
183
+ it 'returns duplicated object, and these event_type_name should be updated with true argument' do
164
184
  x = set.dup
165
185
  x.bind('TargetExample', :data)
166
186
 
167
- y = x.rebind
187
+ y = x.rebind(true)
168
188
  expect(y.summary).to eql(x.summary)
169
189
  expect(y.fields.values.map(&:to_hash)).to eql(x.fields.values.map(&:to_hash))
170
190
  expect(y.target).to eql(x.target)
data/spec/typedef_spec.rb CHANGED
@@ -45,6 +45,8 @@ describe Norikra::Typedef do
45
45
  it 'stores all fields in specified fieldset' do
46
46
  t = Norikra::Typedef.new
47
47
  set = Norikra::FieldSet.new({'a'=>'string','b'=>'long','c'=>'double'})
48
+ set.target = 'testing'
49
+ set.level = :base
48
50
  t.activate(set)
49
51
  expect(t.fields.size).to eql(3)
50
52
  expect(t.fields['a'].optional?).to be_false
@@ -198,7 +200,7 @@ describe Norikra::Typedef do
198
200
  expect(t.instance_eval{ @set_map['a,b'].event_type_name }).to eql(set1.event_type_name)
199
201
  expect(t.instance_eval{ @datafieldsets.size }).to eql(1)
200
202
 
201
- set2 = set1.rebind
203
+ set2 = set1.rebind(true) # replacing needs updated event_type_name
202
204
  t.replace(:data, set1, set2)
203
205
  expect(t.instance_eval{ @datafieldsets.size }).to eql(1)
204
206
  expect(t.instance_eval{ @set_map['a,b'].event_type_name }).not_to eql(set1.event_type_name)
metadata CHANGED
@@ -2,26 +2,26 @@
2
2
  name: norikra
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.4
5
+ version: 0.0.5
6
6
  platform: java
7
7
  authors:
8
8
  - TAGOMORI Satoshi
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-30 00:00:00.000000000 Z
12
+ date: 2013-07-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mizuno
16
16
  version_requirements: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - "~>"
18
+ - - ~>
19
19
  - !ruby/object:Gem::Version
20
20
  version: '0.6'
21
21
  none: false
22
22
  requirement: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.6'
27
27
  none: false
@@ -31,17 +31,15 @@ dependencies:
31
31
  name: rack
32
32
  version_requirements: !ruby/object:Gem::Requirement
33
33
  requirements:
34
- - - ">="
34
+ - - '>='
35
35
  - !ruby/object:Gem::Version
36
- version: !binary |-
37
- MA==
36
+ version: '0'
38
37
  none: false
39
38
  requirement: !ruby/object:Gem::Requirement
40
39
  requirements:
41
- - - ">="
40
+ - - '>='
42
41
  - !ruby/object:Gem::Version
43
- version: !binary |-
44
- MA==
42
+ version: '0'
45
43
  none: false
46
44
  prerelease: false
47
45
  type: :runtime
@@ -49,15 +47,15 @@ dependencies:
49
47
  name: msgpack-rpc-over-http-jruby
50
48
  version_requirements: !ruby/object:Gem::Requirement
51
49
  requirements:
52
- - - ">="
50
+ - - '>='
53
51
  - !ruby/object:Gem::Version
54
- version: 0.0.5.jruby1
52
+ version: 0.0.5
55
53
  none: false
56
54
  requirement: !ruby/object:Gem::Requirement
57
55
  requirements:
58
- - - ">="
56
+ - - '>='
59
57
  - !ruby/object:Gem::Version
60
- version: 0.0.5.jruby1
58
+ version: 0.0.5
61
59
  none: false
62
60
  prerelease: false
63
61
  type: :runtime
@@ -65,17 +63,15 @@ dependencies:
65
63
  name: thor
66
64
  version_requirements: !ruby/object:Gem::Requirement
67
65
  requirements:
68
- - - ">="
66
+ - - '>='
69
67
  - !ruby/object:Gem::Version
70
- version: !binary |-
71
- MA==
68
+ version: '0'
72
69
  none: false
73
70
  requirement: !ruby/object:Gem::Requirement
74
71
  requirements:
75
- - - ">="
72
+ - - '>='
76
73
  - !ruby/object:Gem::Version
77
- version: !binary |-
78
- MA==
74
+ version: '0'
79
75
  none: false
80
76
  prerelease: false
81
77
  type: :runtime
@@ -83,15 +79,15 @@ dependencies:
83
79
  name: norikra-client-jruby
84
80
  version_requirements: !ruby/object:Gem::Requirement
85
81
  requirements:
86
- - - ">="
82
+ - - '>='
87
83
  - !ruby/object:Gem::Version
88
- version: 0.0.3
84
+ version: 0.0.4
89
85
  none: false
90
86
  requirement: !ruby/object:Gem::Requirement
91
87
  requirements:
92
- - - ">="
88
+ - - '>='
93
89
  - !ruby/object:Gem::Version
94
- version: 0.0.3
90
+ version: 0.0.4
95
91
  none: false
96
92
  prerelease: false
97
93
  type: :runtime
@@ -99,13 +95,13 @@ dependencies:
99
95
  name: bundler
100
96
  version_requirements: !ruby/object:Gem::Requirement
101
97
  requirements:
102
- - - "~>"
98
+ - - ~>
103
99
  - !ruby/object:Gem::Version
104
100
  version: '1.3'
105
101
  none: false
106
102
  requirement: !ruby/object:Gem::Requirement
107
103
  requirements:
108
- - - "~>"
104
+ - - ~>
109
105
  - !ruby/object:Gem::Version
110
106
  version: '1.3'
111
107
  none: false
@@ -115,17 +111,15 @@ dependencies:
115
111
  name: rake
116
112
  version_requirements: !ruby/object:Gem::Requirement
117
113
  requirements:
118
- - - ">="
114
+ - - '>='
119
115
  - !ruby/object:Gem::Version
120
- version: !binary |-
121
- MA==
116
+ version: '0'
122
117
  none: false
123
118
  requirement: !ruby/object:Gem::Requirement
124
119
  requirements:
125
- - - ">="
120
+ - - '>='
126
121
  - !ruby/object:Gem::Version
127
- version: !binary |-
128
- MA==
122
+ version: '0'
129
123
  none: false
130
124
  prerelease: false
131
125
  type: :development
@@ -133,13 +127,13 @@ dependencies:
133
127
  name: rspec
134
128
  version_requirements: !ruby/object:Gem::Requirement
135
129
  requirements:
136
- - - "~>"
130
+ - - ~>
137
131
  - !ruby/object:Gem::Version
138
132
  version: '2.0'
139
133
  none: false
140
134
  requirement: !ruby/object:Gem::Requirement
141
135
  requirements:
142
- - - "~>"
136
+ - - ~>
143
137
  - !ruby/object:Gem::Version
144
138
  version: '2.0'
145
139
  none: false
@@ -149,17 +143,15 @@ dependencies:
149
143
  name: spork
150
144
  version_requirements: !ruby/object:Gem::Requirement
151
145
  requirements:
152
- - - ">="
146
+ - - '>='
153
147
  - !ruby/object:Gem::Version
154
- version: !binary |-
155
- MA==
148
+ version: '0'
156
149
  none: false
157
150
  requirement: !ruby/object:Gem::Requirement
158
151
  requirements:
159
- - - ">="
152
+ - - '>='
160
153
  - !ruby/object:Gem::Version
161
- version: !binary |-
162
- MA==
154
+ version: '0'
163
155
  none: false
164
156
  prerelease: false
165
157
  type: :development
@@ -167,21 +159,19 @@ dependencies:
167
159
  name: pry
168
160
  version_requirements: !ruby/object:Gem::Requirement
169
161
  requirements:
170
- - - ">="
162
+ - - '>='
171
163
  - !ruby/object:Gem::Version
172
- version: !binary |-
173
- MA==
164
+ version: '0'
174
165
  none: false
175
166
  requirement: !ruby/object:Gem::Requirement
176
167
  requirements:
177
- - - ">="
168
+ - - '>='
178
169
  - !ruby/object:Gem::Version
179
- version: !binary |-
180
- MA==
170
+ version: '0'
181
171
  none: false
182
172
  prerelease: false
183
173
  type: :development
184
- description: ! 'CEP: Complex Event Processor with Esper EPL qeury language, messagepack
174
+ description: 'CEP: Complex Event Processor with Esper EPL qeury language, messagepack
185
175
  rpc for inbound event data'
186
176
  email:
187
177
  - tagomoris@gmail.com
@@ -191,8 +181,8 @@ executables:
191
181
  extensions: []
192
182
  extra_rdoc_files: []
193
183
  files:
194
- - ".gitignore"
195
- - ".ruby-version"
184
+ - .gitignore
185
+ - .ruby-version
196
186
  - Gemfile
197
187
  - LICENSE
198
188
  - README.md
@@ -272,6 +262,8 @@ files:
272
262
  - lib/norikra.rb
273
263
  - lib/norikra/cli.rb
274
264
  - lib/norikra/engine.rb
265
+ - lib/norikra/logger.rb
266
+ - lib/norikra/logger_mizuno_patch.rb
275
267
  - lib/norikra/output_pool.rb
276
268
  - lib/norikra/query.rb
277
269
  - lib/norikra/rpc.rb
@@ -300,17 +292,15 @@ require_paths:
300
292
  - esper
301
293
  required_ruby_version: !ruby/object:Gem::Requirement
302
294
  requirements:
303
- - - ">="
295
+ - - '>='
304
296
  - !ruby/object:Gem::Version
305
- version: !binary |-
306
- MA==
297
+ version: '0'
307
298
  none: false
308
299
  required_rubygems_version: !ruby/object:Gem::Requirement
309
300
  requirements:
310
- - - ">="
301
+ - - '>='
311
302
  - !ruby/object:Gem::Version
312
- version: !binary |-
313
- MA==
303
+ version: '0'
314
304
  none: false
315
305
  requirements: []
316
306
  rubyforge_project: