etna 0.1.46 → 0.1.47
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/commands.rb +54 -1
- data/lib/etna/application.rb +19 -28
- data/lib/etna/auth.rb +2 -2
- data/lib/etna/clients/magma/workflows/materialize_magma_record_files_workflow.rb +4 -0
- data/lib/etna/clients/metis/workflows/sync_metis_data_workflow.rb +41 -22
- data/lib/etna/command.rb +1 -1
- data/lib/etna/controller.rb +1 -1
- data/lib/etna/filesystem.rb +31 -11
- data/lib/etna/instrumentation.rb +56 -0
- data/lib/etna/route.rb +25 -40
- data/lib/etna/user.rb +4 -0
- data/lib/etna.rb +1 -0
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: eb695213d2c20c23465eb992a31fa8b0d30c80d78f0c83f672fbb45317ff33d4
|
|
4
|
+
data.tar.gz: efd86410cf85007a8bd1c957882a44ab5a0334fd0b54b87a8a140ff4203b74c5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c288d8ecc5d518523a9ae7591c1edd8d85030ea84fe0b9f0f468d1f8610b27b7b3d4f4ca3fe28b0cf0f49c77baeedf168707193b95d2489729a6ab6bab966044
|
|
7
|
+
data.tar.gz: e987626f648fee08acd56c5615d63200b5d3813f511a8043d6afa9987f0bdad4fd72e485d25982702ebb748a00f0a7703372fdc45cf962550e171472b17e7ab8
|
data/lib/commands.rb
CHANGED
|
@@ -206,7 +206,7 @@ class EtnaApp
|
|
|
206
206
|
end
|
|
207
207
|
end
|
|
208
208
|
|
|
209
|
-
class
|
|
209
|
+
class Janus
|
|
210
210
|
include Etna::CommandExecutor
|
|
211
211
|
|
|
212
212
|
class Token
|
|
@@ -238,6 +238,59 @@ class EtnaApp
|
|
|
238
238
|
end
|
|
239
239
|
end
|
|
240
240
|
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
class Magma
|
|
244
|
+
include Etna::CommandExecutor
|
|
245
|
+
|
|
246
|
+
class Materialize < Etna::Command
|
|
247
|
+
include WithEtnaClients
|
|
248
|
+
|
|
249
|
+
string_flags << "--project-name"
|
|
250
|
+
string_flags << "--log-file"
|
|
251
|
+
string_flags << "--log-level"
|
|
252
|
+
string_flags << "--concurrency"
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def execute(project_name:, log_file:'/dev/stdout', log_level: ::Logger::INFO, concurrency: 1)
|
|
256
|
+
logger = Etna::Logger.new(log_file, 0, 1048576)
|
|
257
|
+
|
|
258
|
+
logger.level = log_level
|
|
259
|
+
|
|
260
|
+
workflow = Etna::Clients::Magma::MaterializeDataWorkflow.new(
|
|
261
|
+
model_attributes_mask: model_attribute_pairs(project_name),
|
|
262
|
+
record_names: 'all',
|
|
263
|
+
model_filters: {},
|
|
264
|
+
metis_client: metis_client,
|
|
265
|
+
magma_client: magma_client,
|
|
266
|
+
logger: logger,
|
|
267
|
+
project_name: project_name,
|
|
268
|
+
model_name: 'project', filesystem: filesystem,
|
|
269
|
+
concurrency: concurrency.to_i)
|
|
270
|
+
|
|
271
|
+
workflow.materialize_all(project_name)
|
|
272
|
+
logger.info("Done")
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def model_attribute_pairs(project_name)
|
|
276
|
+
models = magma_client.retrieve(Etna::Clients::Magma::RetrievalRequest.new(
|
|
277
|
+
project_name: project_name,
|
|
278
|
+
model_name: 'all',
|
|
279
|
+
attribute_names: 'all',
|
|
280
|
+
record_names: []
|
|
281
|
+
)).models
|
|
282
|
+
|
|
283
|
+
result = models.model_keys.map do |model_name|
|
|
284
|
+
[ model_name, models.model(model_name).template.attributes.attribute_keys ]
|
|
285
|
+
end.to_h
|
|
286
|
+
|
|
287
|
+
result
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
def filesystem
|
|
291
|
+
@filesystem ||= Etna::Filesystem.new
|
|
292
|
+
end
|
|
293
|
+
end
|
|
241
294
|
|
|
242
295
|
class Project
|
|
243
296
|
include Etna::CommandExecutor
|
data/lib/etna/application.rb
CHANGED
|
@@ -68,38 +68,43 @@ module Etna::Application
|
|
|
68
68
|
[path.map(&:to_sym), YAML.load(File.read(value))]
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
+
def controller_tags
|
|
72
|
+
[:controller, :action, :project_name, :user_hash]
|
|
73
|
+
end
|
|
74
|
+
|
|
71
75
|
def setup_yabeda
|
|
72
76
|
application = self.id
|
|
77
|
+
ctags = self.controller_tags
|
|
73
78
|
Yabeda.configure do
|
|
74
79
|
default_tag :application, application
|
|
80
|
+
default_tag :project_name, 'unknown'
|
|
81
|
+
default_tag :controller, 'none'
|
|
82
|
+
default_tag :action, 'none'
|
|
83
|
+
default_tag :user_hash, 'unknown'
|
|
75
84
|
|
|
76
85
|
group :etna do
|
|
77
86
|
histogram :response_time do
|
|
78
87
|
comment "Time spent by a controller returning a response"
|
|
79
88
|
unit :seconds
|
|
80
|
-
tags
|
|
89
|
+
tags ctags
|
|
90
|
+
buckets [0.01, 0.1, 0.3, 0.5, 1, 5]
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
histogram :perf do
|
|
94
|
+
comment "Time spent inside code path"
|
|
95
|
+
unit :seconds
|
|
96
|
+
tags ctags + [:class_name, :method_name]
|
|
81
97
|
buckets [0.01, 0.1, 0.3, 0.5, 1, 5]
|
|
82
98
|
end
|
|
83
99
|
|
|
84
100
|
counter :visits do
|
|
85
101
|
comment "Counts visits to the controller"
|
|
86
|
-
tags
|
|
102
|
+
tags ctags
|
|
87
103
|
end
|
|
88
104
|
|
|
89
105
|
counter :rollbar_errors do
|
|
90
106
|
comment "Counts errors detected by and sent to rollbar"
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
gauge :last_command_completion do
|
|
94
|
-
comment "Unix time of last time command was completed"
|
|
95
|
-
tags [:command, :status, :application]
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
histogram :command_runtime do
|
|
99
|
-
comment "Time spent processing a given command"
|
|
100
|
-
tags [:command, :status, :application]
|
|
101
|
-
unit :seconds
|
|
102
|
-
buckets [0.1, 1, 5, 60, 300, 1500]
|
|
107
|
+
tags ctags
|
|
103
108
|
end
|
|
104
109
|
end
|
|
105
110
|
end
|
|
@@ -176,9 +181,6 @@ module Etna::Application
|
|
|
176
181
|
end
|
|
177
182
|
|
|
178
183
|
def run_command(config, *args, &block)
|
|
179
|
-
application = self.id
|
|
180
|
-
status = 'success'
|
|
181
|
-
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
182
184
|
cmd, cmd_args, cmd_kwds = find_command(*args)
|
|
183
185
|
|
|
184
186
|
begin
|
|
@@ -190,18 +192,7 @@ module Etna::Application
|
|
|
190
192
|
cmd.execute(*cmd.fill_in_missing_params(cmd_args), **cmd_kwds)
|
|
191
193
|
rescue => e
|
|
192
194
|
Rollbar.error(e)
|
|
193
|
-
status = 'failed'
|
|
194
195
|
raise
|
|
195
|
-
ensure
|
|
196
|
-
if defined?(Yabeda) && Yabeda.configured?
|
|
197
|
-
tags = { command: cmd.class.name, status: status, application: application }
|
|
198
|
-
dur = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
|
|
199
|
-
|
|
200
|
-
Yabeda.etna.last_command_completion.set(tags, Time.now.to_i)
|
|
201
|
-
Yabeda.etna.command_runtime.measure(tags, dur)
|
|
202
|
-
|
|
203
|
-
write_job_metrics("run_command.#{cmd.class.name}")
|
|
204
|
-
end
|
|
205
196
|
end
|
|
206
197
|
end
|
|
207
198
|
end
|
data/lib/etna/auth.rb
CHANGED
|
@@ -18,7 +18,7 @@ module Etna
|
|
|
18
18
|
if [ approve_noauth(request), approve_hmac(request), approve_user(request) ].all?{|approved| !approved}
|
|
19
19
|
return fail_or_redirect(request)
|
|
20
20
|
end
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
@app.call(request.env)
|
|
23
23
|
end
|
|
24
24
|
|
|
@@ -97,7 +97,7 @@ module Etna
|
|
|
97
97
|
|
|
98
98
|
return payload unless route
|
|
99
99
|
|
|
100
|
-
begin
|
|
100
|
+
begin
|
|
101
101
|
permissions = permissions(payload)
|
|
102
102
|
|
|
103
103
|
janus.resource_projects(token).each do |resource_project|
|
|
@@ -41,6 +41,7 @@ module Etna
|
|
|
41
41
|
|
|
42
42
|
begin
|
|
43
43
|
if (error = errors.pop(true))
|
|
44
|
+
logger&.error(error)
|
|
44
45
|
raise error
|
|
45
46
|
end
|
|
46
47
|
rescue ThreadError
|
|
@@ -51,6 +52,7 @@ module Etna
|
|
|
51
52
|
begin
|
|
52
53
|
materialize_record(dest, template, document)
|
|
53
54
|
rescue => e
|
|
55
|
+
logger&.error(e)
|
|
54
56
|
errors << e
|
|
55
57
|
ensure
|
|
56
58
|
semaphore.release
|
|
@@ -62,6 +64,7 @@ module Etna
|
|
|
62
64
|
|
|
63
65
|
begin
|
|
64
66
|
if (error = errors.pop(true))
|
|
67
|
+
logger&.error(error)
|
|
65
68
|
raise error
|
|
66
69
|
end
|
|
67
70
|
rescue ThreadError
|
|
@@ -105,6 +108,7 @@ module Etna
|
|
|
105
108
|
end
|
|
106
109
|
|
|
107
110
|
dest_file = File.join(dest_dir, metadata_file_name(record_name: record[template.identifier], record_model_name: template.name, ext: "_#{attr_name}_#{idx}#{File.extname(filename)}"))
|
|
111
|
+
filesystem.mkdir_p(File.dirname(dest_file))
|
|
108
112
|
sync_metis_data_workflow.copy_file(dest: dest_file, url: url, stub: stub_files)
|
|
109
113
|
record_to_serialize[attr_name] << {file: dest_file, original_filename: filename}
|
|
110
114
|
end
|
|
@@ -22,36 +22,56 @@ module Etna
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def copy_file(dest:, url:, stub: false)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
25
|
+
url_match = DOWNLOAD_REGEX.match(url)
|
|
26
|
+
|
|
27
|
+
if filesystem.instance_of?(Etna::Filesystem::Metis) && !url_match.nil?
|
|
28
|
+
bucket_name = url_match[:bucket_name]
|
|
29
|
+
project_name = url_match[:project_name]
|
|
30
|
+
file_path = url_match[:file_path]
|
|
31
|
+
|
|
32
|
+
# ensure target parent directory exists
|
|
33
|
+
metis_client.ensure_parent_folder_exists(
|
|
34
|
+
project_name: filesystem.project_name,
|
|
35
|
+
bucket_name: filesystem.bucket_name,
|
|
36
|
+
path: dest
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
metis_client.copy_files(
|
|
40
|
+
Etna::Clients::Metis::CopyFilesRequest.new(
|
|
41
|
+
project_name: project_name,
|
|
42
|
+
revisions: [
|
|
43
|
+
Etna::Clients::Metis::CopyRevision.new(
|
|
44
|
+
source: "metis://#{project_name}/#{bucket_name}/#{file_path}",
|
|
45
|
+
dest: "metis://#{filesystem.project_name}/#{filesystem.bucket_name}/#{dest}",
|
|
46
|
+
)
|
|
47
|
+
]
|
|
48
|
+
)
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
return
|
|
52
|
+
end
|
|
45
53
|
|
|
46
54
|
metadata = metis_client.file_metadata(url)
|
|
47
55
|
size = metadata[:size]
|
|
48
56
|
|
|
57
|
+
begin
|
|
58
|
+
if filesystem.exist?(dest) && filesystem.stat(dest).size == size
|
|
59
|
+
logger&.info "Already downloaded #{dest}"
|
|
60
|
+
return
|
|
61
|
+
end
|
|
62
|
+
rescue Etna::Filesystem::Error => e
|
|
63
|
+
unless e.message =~ /stat not supported/
|
|
64
|
+
raise e
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
49
68
|
tmp_file = dest
|
|
50
69
|
upload_timings = []
|
|
51
70
|
upload_amount = 0
|
|
52
71
|
last_rate = 0.00001
|
|
53
72
|
remaining = size
|
|
54
73
|
|
|
74
|
+
logger&.info "Downloading #{dest} - #{Etna::Formatting.as_size(size)}"
|
|
55
75
|
filesystem.with_writeable(tmp_file, "w", size_hint: size) do |io|
|
|
56
76
|
if stub
|
|
57
77
|
io.write("(stub) #{size} bytes")
|
|
@@ -78,7 +98,7 @@ module Etna
|
|
|
78
98
|
rate = upload_amount / (end_time - start_time)
|
|
79
99
|
|
|
80
100
|
if rate / last_rate > 1.3 || rate / last_rate < 0.7
|
|
81
|
-
logger&.
|
|
101
|
+
logger&.debug("Uploading #{Etna::Formatting.as_size(rate)} per second, #{Etna::Formatting.as_size(remaining)} remaining")
|
|
82
102
|
|
|
83
103
|
if rate == 0
|
|
84
104
|
last_rate = 0.0001
|
|
@@ -87,7 +107,6 @@ module Etna
|
|
|
87
107
|
end
|
|
88
108
|
end
|
|
89
109
|
end
|
|
90
|
-
|
|
91
110
|
end
|
|
92
111
|
end
|
|
93
112
|
end
|
data/lib/etna/command.rb
CHANGED
data/lib/etna/controller.rb
CHANGED
|
@@ -133,7 +133,7 @@ MESSAGE_END
|
|
|
133
133
|
end
|
|
134
134
|
|
|
135
135
|
def config_hosts
|
|
136
|
-
[:janus, :magma, :timur, :metis, :vulcan, :polyphemus].map do |host|
|
|
136
|
+
[:janus, :magma, :timur, :metis, :vulcan, :polyphemus, :gnomon].map do |host|
|
|
137
137
|
[ :"#{host}_host", @server.send(:application).config(host)&.dig(:host) ]
|
|
138
138
|
end.to_h.compact
|
|
139
139
|
end
|
data/lib/etna/filesystem.rb
CHANGED
|
@@ -14,45 +14,48 @@ module Etna
|
|
|
14
14
|
::File.open(dest, opts, &block)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
+
class Error < StandardError
|
|
18
|
+
end
|
|
19
|
+
|
|
17
20
|
def ls(dir)
|
|
18
|
-
raise "ls not supported by #{self.class.name}" unless self.class == Filesystem
|
|
21
|
+
raise Etna::Filesystem::Error, "ls not supported by #{self.class.name}" unless self.class == Filesystem
|
|
19
22
|
::Dir.entries(dir).select { |p| !p.start_with?('.') }.map do |path|
|
|
20
23
|
::File.file?(::File.join(dir, path)) ? [:file, path] : [:dir, path]
|
|
21
24
|
end
|
|
22
25
|
end
|
|
23
26
|
|
|
24
27
|
def with_readable(src, opts = 'r', &block)
|
|
25
|
-
raise "with_readable not supported by #{self.class.name}" unless self.class == Filesystem
|
|
28
|
+
raise Etna::Filesystem::Error, "with_readable not supported by #{self.class.name}" unless self.class == Filesystem
|
|
26
29
|
::File.open(src, opts, &block)
|
|
27
30
|
end
|
|
28
31
|
|
|
29
32
|
def mkdir_p(dir)
|
|
30
|
-
raise "mkdir_p not supported by #{self.class.name}" unless self.class == Filesystem
|
|
33
|
+
raise Etna::Filesystem::Error, "mkdir_p not supported by #{self.class.name}" unless self.class == Filesystem
|
|
31
34
|
::FileUtils.mkdir_p(dir)
|
|
32
35
|
end
|
|
33
36
|
|
|
34
37
|
def rm_rf(dir)
|
|
35
|
-
raise "rm_rf not supported by #{self.class.name}" unless self.class == Filesystem
|
|
38
|
+
raise Etna::Filesystem::Error, "rm_rf not supported by #{self.class.name}" unless self.class == Filesystem
|
|
36
39
|
::FileUtils.rm_rf(dir)
|
|
37
40
|
end
|
|
38
41
|
|
|
39
42
|
def tmpdir
|
|
40
|
-
raise "tmpdir not supported by #{self.class.name}" unless self.class == Filesystem
|
|
43
|
+
raise Etna::Filesystem::Error, "tmpdir not supported by #{self.class.name}" unless self.class == Filesystem
|
|
41
44
|
::Dir.mktmpdir
|
|
42
45
|
end
|
|
43
46
|
|
|
44
47
|
def exist?(src)
|
|
45
|
-
raise "exist? not supported by #{self.class.name}" unless self.class == Filesystem
|
|
48
|
+
raise Etna::Filesystem::Error, "exist? not supported by #{self.class.name}" unless self.class == Filesystem
|
|
46
49
|
::File.exist?(src)
|
|
47
50
|
end
|
|
48
51
|
|
|
49
52
|
def mv(src, dest)
|
|
50
|
-
raise "mv not supported by #{self.class.name}" unless self.class == Filesystem
|
|
53
|
+
raise Etna::Filesystem::Error, "mv not supported by #{self.class.name}" unless self.class == Filesystem
|
|
51
54
|
::FileUtils.mv(src, dest)
|
|
52
55
|
end
|
|
53
56
|
|
|
54
57
|
def stat(src)
|
|
55
|
-
raise "stat not supported by #{self.class.name}" unless self.class == Filesystem
|
|
58
|
+
raise Etna::Filesystem::Error, "stat not supported by #{self.class.name}" unless self.class == Filesystem
|
|
56
59
|
::File.stat(src)
|
|
57
60
|
end
|
|
58
61
|
|
|
@@ -66,7 +69,9 @@ module Etna
|
|
|
66
69
|
def mkio(file, opts, size_hint: nil, &block)
|
|
67
70
|
rd, wd = IO.pipe
|
|
68
71
|
|
|
69
|
-
|
|
72
|
+
cmd = mkcommand(rd, wd, file, opts, size_hint: size_hint)
|
|
73
|
+
puts "in mkio: #{cmd}"
|
|
74
|
+
pid = spawn(*cmd)
|
|
70
75
|
q = Queue.new
|
|
71
76
|
|
|
72
77
|
closer = Thread.new do
|
|
@@ -184,9 +189,22 @@ module Etna
|
|
|
184
189
|
cmd << @key_file
|
|
185
190
|
end
|
|
186
191
|
|
|
192
|
+
cmd << "-O"
|
|
193
|
+
cmd << @port.to_s
|
|
194
|
+
|
|
187
195
|
cmd << "-P"
|
|
188
196
|
cmd << @port.to_s
|
|
189
197
|
|
|
198
|
+
cmd << "-v"
|
|
199
|
+
cmd << "-k"
|
|
200
|
+
cmd << "0"
|
|
201
|
+
cmd << "--file-manifest=text"
|
|
202
|
+
cmd << "--file-manifest-path=/var/tmp"
|
|
203
|
+
cmd << "--file-checksum=md5"
|
|
204
|
+
cmd << "-l"
|
|
205
|
+
cmd << "100m"
|
|
206
|
+
cmd << "--overwrite=always"
|
|
207
|
+
|
|
190
208
|
remote_path = file
|
|
191
209
|
# https://download.asperasoft.com/download/docs/entsrv/3.9.1/es_admin_linux/webhelp/index.html#dita/stdio_2.html
|
|
192
210
|
local_path = "stdio://"
|
|
@@ -212,6 +230,7 @@ module Etna
|
|
|
212
230
|
cmd << {in: rd}
|
|
213
231
|
end
|
|
214
232
|
|
|
233
|
+
puts "end of mkcmd: #{cmd}"
|
|
215
234
|
cmd
|
|
216
235
|
end
|
|
217
236
|
end
|
|
@@ -228,7 +247,8 @@ module Etna
|
|
|
228
247
|
if e.instance_of?(String) && e.start_with?("stdio://")
|
|
229
248
|
"stdio-tar://"
|
|
230
249
|
elsif e == file
|
|
231
|
-
::File.dirname(file)
|
|
250
|
+
dir = ::File.dirname(file)
|
|
251
|
+
dir[0] == '/' ? dir : "/#{dir}"
|
|
232
252
|
else
|
|
233
253
|
e
|
|
234
254
|
end
|
|
@@ -565,4 +585,4 @@ module Etna
|
|
|
565
585
|
end
|
|
566
586
|
end
|
|
567
587
|
end
|
|
568
|
-
end
|
|
588
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module Etna
|
|
2
|
+
module Instrumentation
|
|
3
|
+
def self.included(cls)
|
|
4
|
+
cls.instance_eval do
|
|
5
|
+
def self.time_it(method_name, &metric_block)
|
|
6
|
+
orig_method_name = :"#{method_name}_without_time_it"
|
|
7
|
+
self.alias_method orig_method_name, method_name
|
|
8
|
+
|
|
9
|
+
self.define_method method_name do |*args|
|
|
10
|
+
time_it(orig_method_name, args, &metric_block)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def increment_it(&block)
|
|
17
|
+
if has_yabeda?
|
|
18
|
+
metric = yield
|
|
19
|
+
metric.increment({})
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def time_it(method_name, args, &metric_block)
|
|
24
|
+
if has_yabeda?
|
|
25
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
26
|
+
begin
|
|
27
|
+
return send(method_name, *args)
|
|
28
|
+
ensure
|
|
29
|
+
dur = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
|
|
30
|
+
if block_given?
|
|
31
|
+
metric = yield
|
|
32
|
+
tags = {}
|
|
33
|
+
else
|
|
34
|
+
tags = {class_name: self.class.name, method_name: method_name.to_s}
|
|
35
|
+
metric = Yabeda.etna.perf
|
|
36
|
+
end
|
|
37
|
+
metric.measure(tags, dur)
|
|
38
|
+
end
|
|
39
|
+
else
|
|
40
|
+
return send(method_name, *args, **kwds)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def with_yabeda_tags(tags, &block)
|
|
45
|
+
if has_yabeda?
|
|
46
|
+
Yabeda.with_tags(tags, &block)
|
|
47
|
+
else
|
|
48
|
+
yield
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def has_yabeda?
|
|
53
|
+
defined?(Yabeda) && Yabeda.configured?
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
data/lib/etna/route.rb
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
require 'digest'
|
|
2
2
|
require 'date'
|
|
3
|
+
require "addressable/uri"
|
|
3
4
|
require_relative "./censor"
|
|
5
|
+
require_relative './instrumentation'
|
|
4
6
|
|
|
5
7
|
module Etna
|
|
6
8
|
class Route
|
|
9
|
+
include Etna::Instrumentation
|
|
10
|
+
|
|
7
11
|
attr_reader :name
|
|
8
12
|
|
|
9
13
|
def initialize(method, route, options, &block)
|
|
@@ -42,7 +46,7 @@ module Etna
|
|
|
42
46
|
if params
|
|
43
47
|
PARAM_TYPES.reduce(route) do |path,pat|
|
|
44
48
|
path.gsub(pat) do
|
|
45
|
-
params[$1.to_sym].split('/').map { |c| block_given? ? yield(c) : URI.
|
|
49
|
+
params[$1.to_sym].split('/').map { |c| block_given? ? yield(c) : Addressable::URI.normalized_encode(c) }.join('/')
|
|
46
50
|
end
|
|
47
51
|
end
|
|
48
52
|
else
|
|
@@ -64,19 +68,27 @@ module Etna
|
|
|
64
68
|
end
|
|
65
69
|
|
|
66
70
|
def call(app, request)
|
|
67
|
-
|
|
71
|
+
update_params(request)
|
|
68
72
|
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
tags = {}
|
|
74
|
+
if @action
|
|
75
|
+
tags[:controller], tags[:action] = @action.split('#')
|
|
76
|
+
elsif @name
|
|
77
|
+
tags[:action] = @name
|
|
78
|
+
else
|
|
79
|
+
tags[:action] = @route
|
|
71
80
|
end
|
|
72
81
|
|
|
73
|
-
|
|
82
|
+
params = request.env['rack.request.params']
|
|
83
|
+
user = request.env['etna.user']
|
|
84
|
+
tags[:user_hash] = user ? hash_user_email(user.email) : 'unknown'
|
|
85
|
+
if params && (params.include?(:project_name) || params.include?('project_name'))
|
|
86
|
+
tags[:project_name] = params[:project_name] || params['project_name']
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
with_yabeda_tags(tags) do
|
|
90
|
+
increment_it { Yabeda.etna.visits }
|
|
74
91
|
process_call(app, request)
|
|
75
|
-
ensure
|
|
76
|
-
try_yabeda(request) do |tags|
|
|
77
|
-
dur = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
|
|
78
|
-
Yabeda.etna.response_time.measure(tags, dur)
|
|
79
|
-
end
|
|
80
92
|
end
|
|
81
93
|
end
|
|
82
94
|
|
|
@@ -93,36 +105,7 @@ module Etna
|
|
|
93
105
|
Digest::MD5.hexdigest(digest)
|
|
94
106
|
end
|
|
95
107
|
|
|
96
|
-
def try_yabeda(request, &block)
|
|
97
|
-
if @action
|
|
98
|
-
controller, action = @action.split('#')
|
|
99
|
-
elsif @name
|
|
100
|
-
controller = "none"
|
|
101
|
-
action = @name
|
|
102
|
-
else
|
|
103
|
-
controller = "none"
|
|
104
|
-
action = @route
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
params = request.env['rack.request.params']
|
|
108
|
-
user = request.env['etna.user']
|
|
109
|
-
user_hash = user ? hash_user_email(user.email) : 'unknown'
|
|
110
|
-
project_name = "unknown"
|
|
111
|
-
|
|
112
|
-
if params && (params.include?(:project_name) || params.include?('project_name'))
|
|
113
|
-
project_name = params[:project_name] || params['project_name']
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
begin
|
|
117
|
-
block.call({ controller: controller, action: action, user_hash: user_hash, project_name: project_name })
|
|
118
|
-
rescue => e
|
|
119
|
-
raise e unless Etna::Application.instance.environment == :production
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
|
|
123
108
|
def process_call(app, request)
|
|
124
|
-
update_params(request)
|
|
125
|
-
|
|
126
109
|
unless authorized?(request)
|
|
127
110
|
if cc_available?(request)
|
|
128
111
|
if request.content_type == 'application/json'
|
|
@@ -155,6 +138,8 @@ module Etna
|
|
|
155
138
|
end
|
|
156
139
|
end
|
|
157
140
|
|
|
141
|
+
time_it(:process_call) { Yabeda.etna.response_time }
|
|
142
|
+
|
|
158
143
|
# the route does not require authorization
|
|
159
144
|
def noauth?
|
|
160
145
|
@auth && @auth[:noauth]
|
|
@@ -256,7 +241,7 @@ module Etna
|
|
|
256
241
|
Hash[
|
|
257
242
|
match.names.map(&:to_sym).zip(
|
|
258
243
|
match.captures.map do |capture|
|
|
259
|
-
capture.split('/').map {|c| URI.
|
|
244
|
+
capture.split('/').map {|c| Addressable::URI.unencode_component(c) }.join('/')
|
|
260
245
|
end
|
|
261
246
|
)
|
|
262
247
|
]
|
data/lib/etna/user.rb
CHANGED
data/lib/etna.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: etna
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.47
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Saurabh Asthana
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2023-01-25 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rack
|
|
@@ -200,6 +200,7 @@ files:
|
|
|
200
200
|
- lib/etna/generate_autocompletion_script.rb
|
|
201
201
|
- lib/etna/hmac.rb
|
|
202
202
|
- lib/etna/injection.rb
|
|
203
|
+
- lib/etna/instrumentation.rb
|
|
203
204
|
- lib/etna/janus_utils.rb
|
|
204
205
|
- lib/etna/json_serializable_struct.rb
|
|
205
206
|
- lib/etna/logger.rb
|
|
@@ -240,8 +241,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
240
241
|
- !ruby/object:Gem::Version
|
|
241
242
|
version: '0'
|
|
242
243
|
requirements: []
|
|
243
|
-
|
|
244
|
-
rubygems_version: 2.7.6.3
|
|
244
|
+
rubygems_version: 3.1.6
|
|
245
245
|
signing_key:
|
|
246
246
|
specification_version: 4
|
|
247
247
|
summary: Base classes for Mount Etna applications
|