norikra 0.0.16-java → 0.0.17-java

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ test/tmp
15
15
  test/version_tmp
16
16
  tmp
17
17
  vendor/
18
+ dump.json
data/Rakefile CHANGED
@@ -6,5 +6,16 @@ RSpec::Core::RakeTask.new(:spec) do |t|
6
6
  t.pattern = 'spec/**/*_spec.rb'
7
7
  end
8
8
 
9
+ task :devstart do |t|
10
+ require 'pathname'
11
+ libs = ['lib', 'esper'].map{|p| Pathname.new(__FILE__).dirname.join('.', p).expand_path}
12
+ $LOAD_PATH.unshift(*libs.map(&:to_s))
13
+
14
+ ARGV.clear
15
+ ARGV.push("start", "--more-verbose", "-Xmx1500m", "--stats", "dump.json")
16
+ require 'norikra/cli'
17
+ Norikra::CLI.start
18
+ end
19
+
9
20
  task :test => :spec
10
21
  task :default => :spec
data/lib/norikra/cli.rb CHANGED
@@ -46,6 +46,7 @@ module Norikra
46
46
  option :'timer-thread-capacity', :type => :numeric, :default => nil
47
47
  # Jetty
48
48
  option :'rpc-threads', :type => :numeric, :default => nil, :desc => 'number of threads for rpc handlers'
49
+ option :'web-threads', :type => :numeric, :default => nil, :desc => 'number of threads for WebUI handlers'
49
50
 
50
51
  ### Logging options
51
52
  option :logdir, :type => :string, :default => nil, :aliases => "-l", \
@@ -140,12 +141,14 @@ module Norikra
140
141
  micro: options[:micro], small: options[:small], middle: options[:middle], large: options[:large],
141
142
  engine: {inbound:{}, outbound:{}, route_exec:{}, timer_exec:{}},
142
143
  rpc: {},
144
+ web: {},
143
145
  }
144
146
  [:inbound, :outbound, :route_exec, :timer_exec].each do |sym|
145
147
  conf[:thread][:engine][sym][:threads] = options[:"#{sym}-threads"] if options[:"#{sym}-threads"]
146
148
  conf[:thread][:engine][sym][:capacity] = options[:"#{sym}-thread-capacity"] if options[:"#{sym}-thread-capacity"]
147
149
  end
148
150
  conf[:thread][:rpc][:threads] = options[:'rpc-threads'] if options[:'rpc-threads']
151
+ conf[:thread][:web][:threads] = options[:'web-threads'] if options[:'web-threads']
149
152
 
150
153
  ### logs
151
154
  loglevel = case
@@ -18,6 +18,11 @@ module Norikra
18
18
  attr_reader :targets, :queries, :output_pool, :typedef_manager
19
19
 
20
20
  def initialize(output_pool, typedef_manager, opts={})
21
+ @statistics = {
22
+ started: Time.now,
23
+ events: { input: 0, processed: 0, output: 0, },
24
+ }
25
+
21
26
  @output_pool = output_pool
22
27
  @typedef_manager = typedef_manager
23
28
 
@@ -36,6 +41,53 @@ module Norikra
36
41
  @waiting_queries = []
37
42
  end
38
43
 
44
+ def statistics
45
+ s = @statistics
46
+ {
47
+ started: s[:started].httpdate,
48
+ uptime: self.uptime,
49
+ memory: self.memory_statistics,
50
+ input_events: s[:events][:input],
51
+ processed_events: s[:events][:processed],
52
+ output_events: s[:events][:output],
53
+ queries: @queries.size,
54
+ targets: @targets.size,
55
+ }
56
+ end
57
+
58
+ def uptime
59
+ # up 239 days, 20:40
60
+ seconds = (Time.now - @statistics[:started]).to_i
61
+ days = seconds / (24*60*60)
62
+ hours = (seconds - days * (24*60*60)) / (60*60)
63
+ minutes = (seconds - days * (24*60*60) - hours * (60*60)) / 60
64
+ "#{days} days, #{sprintf("%02d", hours)}:#{sprintf("%02d", minutes)}"
65
+ end
66
+
67
+ def memory_statistics
68
+ mb = 1024 * 1024
69
+
70
+ memoryBean = Java::JavaLangManagement::ManagementFactory.getMemoryMXBean()
71
+
72
+ usage = memoryBean.getHeapMemoryUsage()
73
+ total = usage.getMax() / mb
74
+ committed = usage.getCommitted() / mb
75
+ committed_percent = (committed.to_f / total * 1000).floor / 10.0
76
+ used = usage.getUsed() / mb
77
+ used_percent = (used.to_f / total * 1000).floor / 10.0
78
+ heap = { max: total, committed: committed, committed_percent: committed_percent, used: used, used_percent: used_percent }
79
+
80
+ usage = memoryBean.getNonHeapMemoryUsage()
81
+ total = usage.getMax() / mb
82
+ committed = usage.getCommitted() / mb
83
+ committed_percent = (committed.to_f / total * 1000).floor / 10.0
84
+ used = usage.getUsed() / mb
85
+ used_percent = (used.to_f / total * 1000).floor / 10.0
86
+ non_heap = { max: total, committed: committed, committed_percent: committed_percent, used: used, used_percent: used_percent }
87
+
88
+ { heap: heap, nonheap: non_heap }
89
+ end
90
+
39
91
  def camelize(sym)
40
92
  sym.to_s.split(/_/).map(&:capitalize).join
41
93
  end
@@ -133,6 +185,9 @@ module Norikra
133
185
 
134
186
  def send(target_name, events)
135
187
  trace "send messages", :target => target_name, :events => events
188
+
189
+ @statistics[:events][:input] += events.size
190
+
136
191
  unless @targets.any?{|t| t.name == target_name} # discard events for target not registered
137
192
  trace "messages skipped for non-opened target", :target => target_name
138
193
  return
@@ -175,6 +230,7 @@ module Norikra
175
230
  trace "sendEvent", :data => formed
176
231
  @runtime.sendEvent(formed.to_java, fieldset.event_type_name)
177
232
  end
233
+ @statistics[:events][:processed] += events.size
178
234
  nil
179
235
  end
180
236
 
@@ -213,6 +269,7 @@ module Norikra
213
269
  events = new_events.map{|e| [t, type_convert(e)]}
214
270
  trace "updated event", :query => @query_name, :group => @query_group, :event => events
215
271
  @output_pool.push(@query_name, @query_group, events)
272
+ @statistics[:events][:output] += events.size
216
273
  end
217
274
  end
218
275
  ##### Unmatched events are simply ignored
@@ -117,6 +117,8 @@ module Norikra
117
117
  end
118
118
  end
119
119
 
120
+ def self.logger; @@logger ; end
121
+
120
122
  def trace(message, data=nil)
121
123
  return if LEVEL_TRACE < @@levelnum
122
124
  from = @@devmode ? caller_locations(1,1) : nil
data/lib/norikra/query.rb CHANGED
@@ -14,8 +14,11 @@ module Norikra
14
14
 
15
15
  def initialize(param={})
16
16
  @name = param[:name]
17
+ raise Norikra::ArgumentError, "Query name MUST NOT be blank" if @name.nil? || @name.empty?
17
18
  @group = param[:group] # default nil
18
19
  @expression = param[:expression]
20
+ raise Norikra::ArgumentError, "Query expression MUST NOT be blank" if @expression.nil? || @expression.empty?
21
+
19
22
  @statement_name = nil
20
23
  @fieldsets = {} # { target => fieldset }
21
24
  @ast = nil
@@ -25,6 +28,22 @@ module Norikra
25
28
  @fields = nil
26
29
  end
27
30
 
31
+ def <=>(other)
32
+ if @group.nil? || other.group.nil?
33
+ if @group.nil? && other.group.nil?
34
+ @name <=> other.name
35
+ else
36
+ @group.to_s <=> other.group.to_s
37
+ end
38
+ else
39
+ if @group == other.group
40
+ self.name <=> other.name
41
+ else
42
+ self.group <=> other.group
43
+ end
44
+ end
45
+ end
46
+
28
47
  def dup
29
48
  self.class.new(:name => @name, :group => @group, :expression => @expression.dup)
30
49
  end
@@ -33,6 +52,10 @@ module Norikra
33
52
  {'name' => @name, 'group' => @group, 'expression' => @expression, 'targets' => self.targets}
34
53
  end
35
54
 
55
+ def dump
56
+ {name: @name, group: @group, expression: @expression}
57
+ end
58
+
36
59
  def targets
37
60
  return @targets if @targets
38
61
  @targets = (self.ast.listup(:stream).map(&:target) + self.subqueries.map(&:targets).flatten).sort.uniq
@@ -167,7 +190,7 @@ module Norikra
167
190
  # model.getWhereClause.getChildren[1].getChildren[0].getPropertyName #=> 'field.key1.$1'
168
191
  # model.getWhereClause.getChildren[2].getChildren[0].getChain[0].getName #=> 'opts.num.$0' from opts.num.$0.length()
169
192
 
170
- query = Norikra::Query.new(:expression => statement_model.toEPL)
193
+ query = Norikra::Query.new(:name => 'dummy name by .rewrite_event_field_name', :expression => statement_model.toEPL)
171
194
  targets = query.targets
172
195
  fqfs_prefixes = targets + query.aliases
173
196
 
@@ -9,7 +9,7 @@ class Norikra::RPC::Handler
9
9
  @engine = engine
10
10
  end
11
11
 
12
- def logging(type, handler, *args)
12
+ def logging(type, handler, args=[])
13
13
  if type == :manage
14
14
  debug "RPC", :handler => handler.to_s, :args => args
15
15
  else
@@ -37,21 +37,21 @@ class Norikra::RPC::Handler
37
37
  end
38
38
 
39
39
  def open(target, fields, auto_field)
40
- logging(:manage, :open, target, fields){
40
+ logging(:manage, :open, [target, fields]){
41
41
  r = @engine.open(target, fields, auto_field)
42
42
  !!r
43
43
  }
44
44
  end
45
45
 
46
46
  def close(target)
47
- logging(:manage, :close, target){
47
+ logging(:manage, :close, [target]){
48
48
  r = @engine.close(target)
49
49
  !!r
50
50
  }
51
51
  end
52
52
 
53
53
  def modify(target, auto_field)
54
- logging(:manage, :modify, target, auto_field){
54
+ logging(:manage, :modify, [target, auto_field]){
55
55
  r = @engine.modify(target, auto_field)
56
56
  !!r
57
57
  }
@@ -64,41 +64,41 @@ class Norikra::RPC::Handler
64
64
  end
65
65
 
66
66
  def register(query_name, query_group, expression)
67
- logging(:manage, :register, query_name, query_group, expression){
67
+ logging(:manage, :register, [query_name, query_group, expression]){
68
68
  r = @engine.register(Norikra::Query.new(:name => query_name, :group => query_group, :expression => expression))
69
69
  !!r
70
70
  }
71
71
  end
72
72
 
73
73
  def deregister(query_name)
74
- logging(:manage, :deregister, query_name){
74
+ logging(:manage, :deregister, [query_name]){
75
75
  r = @engine.deregister(query_name)
76
76
  !!r
77
77
  }
78
78
  end
79
79
 
80
80
  def fields(target)
81
- logging(:show, :fields, target){
81
+ logging(:show, :fields, [target]){
82
82
  @engine.typedef_manager.field_list(target)
83
83
  }
84
84
  end
85
85
 
86
86
  def reserve(target, fieldname, type)
87
- logging(:manage, :reserve, target, fieldname, type){
87
+ logging(:manage, :reserve, [target, fieldname, type]){
88
88
  r = @engine.reserve(target, fieldname, type)
89
89
  !!r
90
90
  }
91
91
  end
92
92
 
93
93
  def send(target, events)
94
- logging(:data, :send, target, events){
94
+ logging(:data, :send, [target, events]){
95
95
  r = @engine.send(target, events)
96
96
  !!r
97
97
  }
98
98
  end
99
99
 
100
100
  def event(query_name)
101
- logging(:show, :event, query_name){
101
+ logging(:show, :event, [query_name]){
102
102
  @engine.output_pool.pop(query_name)
103
103
  }
104
104
  end
@@ -4,6 +4,9 @@ require 'msgpack-rpc-over-http-jruby'
4
4
 
5
5
  require_relative 'handler'
6
6
 
7
+ require 'norikra/logger'
8
+ include Norikra::Log
9
+
7
10
  module Norikra::RPC
8
11
  class HTTP
9
12
  DEFAULT_LISTEN_HOST = '0.0.0.0'
@@ -27,6 +30,7 @@ module Norikra::RPC
27
30
  end
28
31
 
29
32
  def start
33
+ info "RPC server #{@host}:#{@port}, #{@threads} threads"
30
34
  @thread = Thread.new do
31
35
  @mizuno = Mizuno::Server.new
32
36
  @mizuno.run(@app, :embedded => true, :threads => @threads, :port => @port, :host => @host)
@@ -10,6 +10,8 @@ require 'norikra/typedef'
10
10
  require 'norikra/query'
11
11
 
12
12
  require 'norikra/rpc'
13
+ require 'norikra/webui'
14
+
13
15
  require 'norikra/udf'
14
16
 
15
17
  module Norikra
@@ -20,21 +22,25 @@ module Norikra
20
22
  :engine => { inbound: { threads: 0, capacity: 0 }, outbound: { threads: 0, capacity: 0 },
21
23
  route_exec: { threads: 0, capacity: 0 }, timer_exec: { threads: 0, capacity: 0 }, },
22
24
  :rpc => { threads: 2 },
25
+ :web => { threads: 2 },
23
26
  }
24
27
  SMALL_PREDEFINED = {
25
28
  :engine => { inbound: { threads: 1, capacity: 0 }, outbound: { threads: 1, capacity: 0 },
26
29
  route_exec: { threads: 1, capacity: 0 }, timer_exec: { threads: 1, capacity: 0 }, },
27
30
  :rpc => { threads: 2 },
31
+ :web => { threads: 2 },
28
32
  }
29
33
  MIDDLE_PREDEFINED = {
30
34
  :engine => { inbound: { threads: 4, capacity: 0 }, outbound: { threads: 2, capacity: 0 },
31
35
  route_exec: { threads: 2, capacity: 0 }, timer_exec: { threads: 2, capacity: 0 }, },
32
36
  :rpc => { threads: 4 },
37
+ :web => { threads: 2 },
33
38
  }
34
39
  LARGE_PREDEFINED = {
35
40
  :engine => { inbound: { threads: 6, capacity: 0 }, outbound: { threads: 6, capacity: 0 },
36
41
  route_exec: { threads: 4, capacity: 0 }, timer_exec: { threads: 4, capacity: 0 }, },
37
42
  :rpc => { threads: 8 },
43
+ :web => { threads: 2 },
38
44
  }
39
45
 
40
46
  def self.threading_configuration(conf, stats)
@@ -51,6 +57,7 @@ module Norikra
51
57
  end
52
58
  end
53
59
  threads[:rpc][:threads] = conf[:rpc][:threads] if conf[:rpc][:threads]
60
+ threads[:web][:threads] = conf[:web][:threads] if conf[:web][:threads]
54
61
  threads
55
62
  end
56
63
 
@@ -83,6 +90,7 @@ module Norikra
83
90
 
84
91
  @host = host || (@stats ? @stats.host : nil)
85
92
  @port = port || (@stats ? @stats.port : nil)
93
+ @ui_port = @stats ? @stats.ui_port : nil
86
94
 
87
95
  @thread_conf = self.class.threading_configuration(conf[:thread], @stats)
88
96
  @log_conf = self.class.log_configuration(conf[:log], @stats)
@@ -96,7 +104,17 @@ module Norikra
96
104
  @output_pool = Norikra::OutputPool.new
97
105
 
98
106
  @engine = Norikra::Engine.new(@output_pool, @typedef_manager, {thread: @thread_conf[:engine]})
99
- @rpcserver = Norikra::RPC::HTTP.new(:engine => @engine, :host => @host, :port => @port, :threads => @thread_conf[:rpc][:threads])
107
+
108
+ @rpcserver = Norikra::RPC::HTTP.new(
109
+ :engine => @engine,
110
+ :host => @host, :port => @port,
111
+ :threads => @thread_conf[:rpc][:threads]
112
+ )
113
+ @webserver = Norikra::WebUI::HTTP.new(
114
+ :engine => @engine,
115
+ :host => @host, :port => @ui_port,
116
+ :threads => @thread_conf[:web][:threads]
117
+ )
100
118
  end
101
119
 
102
120
  def run
@@ -113,12 +131,13 @@ module Norikra
113
131
  end
114
132
  if @stats.queries && @stats.queries.size > 0
115
133
  @stats.queries.each do |query|
116
- @engine.register(Norikra::Query.new(:name => query[:name], :expression => query[:expression]))
134
+ @engine.register(Norikra::Query.new(:name => query[:name], :group => query[:group], :expression => query[:expression]))
117
135
  end
118
136
  end
119
137
  end
120
138
 
121
139
  @rpcserver.start
140
+ @webserver.start
122
141
 
123
142
  @running = true
124
143
  info "Norikra server started."
@@ -153,6 +172,7 @@ module Norikra
153
172
 
154
173
  def shutdown
155
174
  info "Norikra server shutting down."
175
+ @webserver.stop
156
176
  @rpcserver.stop
157
177
  @engine.stop
158
178
  info "Norikra server stopped."
@@ -170,7 +190,7 @@ module Norikra
170
190
  :auto_field => t.auto_field
171
191
  }
172
192
  },
173
- queries: @engine.queries.map{|q| {:name => q.name, :expression => q.expression}}
193
+ queries: @engine.queries.map(&:dump)
174
194
  )
175
195
  stats.dump(@stats_path)
176
196
  info "Current status saved", :path => @stats_path
data/lib/norikra/stats.rb CHANGED
@@ -2,12 +2,13 @@ require 'json'
2
2
 
3
3
  module Norikra
4
4
  class Stats
5
- attr_accessor :host, :port, :threads, :log
5
+ attr_accessor :host, :port, :ui_port, :threads, :log
6
6
  attr_accessor :targets, :queries
7
7
 
8
8
  def initialize(opts={})
9
9
  @host = opts[:host]
10
10
  @port = opts[:port]
11
+ @ui_port = opts[:ui_port]
11
12
  @threads = opts[:threads]
12
13
  @log = opts[:log]
13
14
  @targets = opts[:targets] || []
@@ -15,7 +16,7 @@ module Norikra
15
16
  end
16
17
 
17
18
  def to_hash
18
- {host: @host, port: @port, threads: @threads, log: @log, targets: @targets, queries: @queries}
19
+ {host: @host, port: @port, ui_port: @ui_port, threads: @threads, log: @log, targets: @targets, queries: @queries}
19
20
  end
20
21
 
21
22
  def dump(path)
@@ -12,6 +12,10 @@ module Norikra
12
12
  @auto_field = !!auto_field
13
13
  end
14
14
 
15
+ def <=>(other)
16
+ self.name <=> other.name
17
+ end
18
+
15
19
  def to_hash
16
20
  {:name => @name, :auto_field => @auto_field}
17
21
  end
@@ -1,3 +1,3 @@
1
1
  module Norikra
2
- VERSION = "0.0.16"
2
+ VERSION = "0.0.17"
3
3
  end
@@ -0,0 +1,5 @@
1
+ module Norikra::WebUI
2
+ end
3
+
4
+ require 'norikra/webui/handler'
5
+ require 'norikra/webui/http'