onlylogs 0.11.0 → 0.12.0
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/README.md +251 -77
- data/app/assets/images/onlylogs/favicon/apple-touch-icon.png +0 -0
- data/app/assets/images/onlylogs/favicon/favicon-96x96.png +0 -0
- data/app/assets/images/onlylogs/favicon/favicon.ico +0 -0
- data/app/assets/images/onlylogs/favicon/favicon.svg +1 -3
- data/app/assets/images/onlylogs/favicon/web-app-manifest-192x192.png +0 -0
- data/app/assets/images/onlylogs/favicon/web-app-manifest-512x512.png +0 -0
- data/app/assets/images/onlylogs/logo.png +0 -0
- data/app/assets/javascripts/onlylogs/clusterize.js +26 -1
- data/app/channels/onlylogs/logs_channel.rb +14 -9
- data/app/controllers/concerns/onlylogs/authentication.rb +26 -0
- data/app/controllers/onlylogs/application_controller.rb +1 -18
- data/app/controllers/onlylogs/queries_controller.rb +70 -0
- data/app/controllers/onlylogs/viewer_controller.rb +7 -0
- data/app/javascript/onlylogs/controllers/keyboard_shortcuts_controller.js +131 -21
- data/app/javascript/onlylogs/controllers/log_cursor_controller.js +286 -0
- data/app/javascript/onlylogs/controllers/log_streamer_controller.js +42 -2
- data/app/javascript/onlylogs/controllers/match_highlight_controller.js +82 -0
- data/app/javascript/onlylogs/controllers/queries_controller.js +470 -0
- data/app/javascript/onlylogs/controllers/range_slider_controller.js +5 -4
- data/app/javascript/onlylogs/controllers/text_selection_controller.js +136 -15
- data/app/models/onlylogs/file.rb +14 -5
- data/app/models/onlylogs/grep.rb +13 -6
- data/app/models/onlylogs/queries_record.rb +28 -0
- data/app/models/onlylogs/query.rb +29 -0
- data/app/views/onlylogs/logs/index.html.erb +1 -1
- data/app/views/onlylogs/shared/_log_container.html.erb +165 -27
- data/app/views/onlylogs/shared/_log_container_styles.html.erb +729 -44
- data/app/views/onlylogs/shared/_shortcuts_dialog.html.erb +62 -0
- data/bin/super_grep +7 -0
- data/bin/super_ripgrep +5 -0
- data/config/routes.rb +1 -0
- data/lib/onlylogs/configuration.rb +14 -1
- data/lib/onlylogs/http_device.rb +28 -13
- data/lib/onlylogs/version.rb +1 -1
- data/lib/onlylogs.rb +4 -0
- metadata +38 -1
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<%# locals: (modifier_label:) %>
|
|
2
|
+
<%
|
|
3
|
+
sections = [
|
|
4
|
+
["Hold #{modifier_label} and press – anywhere, also while typing", [
|
|
5
|
+
[%w[L], "Live"],
|
|
6
|
+
[%w[S], "Search"],
|
|
7
|
+
[%w[Q], "Go to the query"],
|
|
8
|
+
[%w[X], "Clear the query"],
|
|
9
|
+
[%w[V], "Saved searches: apply, rename or delete one"],
|
|
10
|
+
[%w[F], "Save the query (the star)"],
|
|
11
|
+
[%w[R], "Regexp on/off"],
|
|
12
|
+
[%w[I], "Ignore case on/off"],
|
|
13
|
+
[%w[A], "Autoscroll on/off (live)"],
|
|
14
|
+
[%w[W], "Search the whole file (live)"],
|
|
15
|
+
[%w[G], "Range slider (search), then ← →"],
|
|
16
|
+
[%w[0], "Reset the range (search)"],
|
|
17
|
+
[%w[.], "Stop the search"],
|
|
18
|
+
[%w[C], "Clear the lines"],
|
|
19
|
+
[%w[J], "Jump into the lines"]
|
|
20
|
+
]],
|
|
21
|
+
["When not typing", [
|
|
22
|
+
[%w[/], "Go to the query"],
|
|
23
|
+
[%w[↓ j], "Jump into the lines"],
|
|
24
|
+
[%w[?], "This help"]
|
|
25
|
+
]],
|
|
26
|
+
["In the query", [
|
|
27
|
+
[%w[Enter Esc], "Jump into the lines"]
|
|
28
|
+
]],
|
|
29
|
+
["In the lines", [
|
|
30
|
+
[%w[↑ ↓ k j], "Previous / next line"],
|
|
31
|
+
[%w[PgUp PgDn], "A page up / down"],
|
|
32
|
+
[%w[Home End g G], "First / last line"],
|
|
33
|
+
[%w[← →], "Select the previous / next word"],
|
|
34
|
+
[["Shift ← →"], "Grow the selection by a word"],
|
|
35
|
+
[%w[Enter], "Search the selection, or show around this line"],
|
|
36
|
+
[%w[y], "Copy the line"],
|
|
37
|
+
[%w[Esc], "Clear the selection, then leave the lines"]
|
|
38
|
+
]]
|
|
39
|
+
]
|
|
40
|
+
%>
|
|
41
|
+
<dialog class="onlylogs-shortcuts-dialog" data-keyboard-shortcuts-target="dialog" closedby="any"
|
|
42
|
+
aria-labelledby="onlylogs-shortcuts-title">
|
|
43
|
+
<form method="dialog" class="onlylogs-shortcuts-dialog__header">
|
|
44
|
+
<h2 id="onlylogs-shortcuts-title">Keyboard shortcuts</h2>
|
|
45
|
+
<button aria-label="Close" autofocus>×</button>
|
|
46
|
+
</form>
|
|
47
|
+
<div class="onlylogs-shortcuts-dialog__sections">
|
|
48
|
+
<% sections.each do |title, shortcuts| %>
|
|
49
|
+
<section>
|
|
50
|
+
<h3><%= title %></h3>
|
|
51
|
+
<dl>
|
|
52
|
+
<% shortcuts.each do |keys, description| %>
|
|
53
|
+
<div>
|
|
54
|
+
<dt><% keys.each do |key| %><kbd><%= key %></kbd><% end %></dt>
|
|
55
|
+
<dd><%= description %></dd>
|
|
56
|
+
</div>
|
|
57
|
+
<% end %>
|
|
58
|
+
</dl>
|
|
59
|
+
</section>
|
|
60
|
+
<% end %>
|
|
61
|
+
</div>
|
|
62
|
+
</dialog>
|
data/bin/super_grep
CHANGED
|
@@ -20,6 +20,10 @@ while [[ $# -gt 0 ]]; do
|
|
|
20
20
|
end_position="$2"
|
|
21
21
|
shift 2
|
|
22
22
|
;;
|
|
23
|
+
--case-insensitive)
|
|
24
|
+
case_insensitive=true
|
|
25
|
+
shift
|
|
26
|
+
;;
|
|
23
27
|
--regexp)
|
|
24
28
|
regexp_mode=true
|
|
25
29
|
shift
|
|
@@ -60,6 +64,9 @@ grep_cmd=(grep -E -h) # -h = no filename (portable)
|
|
|
60
64
|
if [ -n "$max_matches" ]; then
|
|
61
65
|
grep_cmd+=(-m "$max_matches") # -m = max count (portable)
|
|
62
66
|
fi
|
|
67
|
+
if [ "$case_insensitive" = true ]; then
|
|
68
|
+
grep_cmd+=(-i)
|
|
69
|
+
fi
|
|
63
70
|
|
|
64
71
|
# Handle byte range if specified
|
|
65
72
|
if [ -n "$start_position" ] || [ -n "$end_position" ]; then
|
data/bin/super_ripgrep
CHANGED
|
@@ -20,6 +20,10 @@ while [[ $# -gt 0 ]]; do
|
|
|
20
20
|
end_position="$2"
|
|
21
21
|
shift 2
|
|
22
22
|
;;
|
|
23
|
+
--case-insensitive)
|
|
24
|
+
case_insensitive=true
|
|
25
|
+
shift
|
|
26
|
+
;;
|
|
23
27
|
--regexp)
|
|
24
28
|
regexp_mode=true
|
|
25
29
|
shift
|
|
@@ -62,6 +66,7 @@ query_regex="${query_regex//$placeholder/$actual_color_regex}"
|
|
|
62
66
|
# --byte-offset: include byte offset in output for the logs-around-line feature
|
|
63
67
|
rg_cmd="rg --color=never --no-filename --byte-offset --no-mmap"
|
|
64
68
|
[ -n "$max_matches" ] && rg_cmd="$rg_cmd --max-count=$max_matches"
|
|
69
|
+
[ "$case_insensitive" = true ] && rg_cmd="$rg_cmd --ignore-case"
|
|
65
70
|
|
|
66
71
|
# Handle byte range if specified
|
|
67
72
|
if [ -n "$start_position" ] || [ -n "$end_position" ]; then
|
data/config/routes.rb
CHANGED
|
@@ -4,7 +4,7 @@ module Onlylogs
|
|
|
4
4
|
class Configuration
|
|
5
5
|
attr_accessor :log_file_patterns, :default_log_file_path, :basic_auth_user, :basic_auth_password,
|
|
6
6
|
:parent_controller, :disable_basic_authentication, :ripgrep_enabled, :editor,
|
|
7
|
-
:max_line_matches, :search_timeout
|
|
7
|
+
:max_line_matches, :search_timeout, :database_dir, :viewer_parent_controller, :authorize_log_file
|
|
8
8
|
|
|
9
9
|
# Seconds a viewer search may run before it is stopped. Bounded by default:
|
|
10
10
|
# a search holds a CPU for as long as it runs, and an unbounded one over a
|
|
@@ -19,11 +19,14 @@ module Onlylogs
|
|
|
19
19
|
@basic_auth_user = default_basic_auth_user
|
|
20
20
|
@basic_auth_password = default_basic_auth_password
|
|
21
21
|
@parent_controller = nil
|
|
22
|
+
@viewer_parent_controller = nil
|
|
23
|
+
@authorize_log_file = nil
|
|
22
24
|
@disable_basic_authentication = false
|
|
23
25
|
@ripgrep_enabled = default_ripgrep_enabled
|
|
24
26
|
@editor = nil
|
|
25
27
|
@max_line_matches = 100000
|
|
26
28
|
@search_timeout = DEFAULT_SEARCH_TIMEOUT
|
|
29
|
+
@database_dir = ".onlylogs"
|
|
27
30
|
end
|
|
28
31
|
|
|
29
32
|
def configure
|
|
@@ -129,6 +132,16 @@ module Onlylogs
|
|
|
129
132
|
configuration.parent_controller
|
|
130
133
|
end
|
|
131
134
|
|
|
135
|
+
def self.viewer_parent_controller
|
|
136
|
+
configuration.viewer_parent_controller
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Runs in the controller, so it can reach the host's current user.
|
|
140
|
+
def self.log_file_authorized?(controller, file_path)
|
|
141
|
+
hook = configuration.authorize_log_file
|
|
142
|
+
hook.nil? || controller.instance_exec(file_path, &hook).present?
|
|
143
|
+
end
|
|
144
|
+
|
|
132
145
|
def self.disable_basic_authentication?
|
|
133
146
|
configuration.disable_basic_authentication
|
|
134
147
|
end
|
data/lib/onlylogs/http_device.rb
CHANGED
|
@@ -7,15 +7,17 @@ require_relative "spool"
|
|
|
7
7
|
# A Logger log device that sends log lines to onlylogs.io (or any Vector-compatible sink) directly
|
|
8
8
|
# via HTTP.
|
|
9
9
|
#
|
|
10
|
+
# Delivery is fire and forget: a batch the drain does not accept within the timeouts is lost.
|
|
10
11
|
# When the drain is unreachable or unresponsive, we do two things to protect the app:
|
|
11
12
|
# * an upper bound to the in-memory queue: log lines can never accumulate without limit and exhaust memory
|
|
12
13
|
# * cooldown: once the drain is known to be failing we stop attempting
|
|
13
14
|
# requests for a cooldown period instead of blocking on every send for the full
|
|
14
15
|
# read timeout (a down host accepts the TCP/TLS connection but never answers).
|
|
15
16
|
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
17
|
+
# ONLYLOGS_SPOOL_ENABLED=true (also 1, yes or on, in any case) opts into an on-disk Spool that
|
|
18
|
+
# buffers any batch we could not deliver and replays it once the drain recovers, so a transient
|
|
19
|
+
# outage or a restart does not lose logs. It lives in ONLYLOGS_SPOOL_DIR and is bounded by bytes;
|
|
20
|
+
# see Onlylogs::Spool.
|
|
19
21
|
#
|
|
20
22
|
# Every write checks that a sender thread is alive in the current process and starts one if not:
|
|
21
23
|
# * The device is usually built in the Puma master (production.rb runs before the workers are
|
|
@@ -28,11 +30,12 @@ require_relative "spool"
|
|
|
28
30
|
#
|
|
29
31
|
# Not every failure is worth retrying. The drain's answer decides what happens to a batch:
|
|
30
32
|
# * 2xx: delivered.
|
|
31
|
-
# * 429: the drain is overloaded and asks us to slow down. Pause for Retry-After (or a cooldown)
|
|
32
|
-
#
|
|
33
|
+
# * 429: the drain is overloaded and asks us to slow down. Pause for Retry-After (or a cooldown);
|
|
34
|
+
# with a spool the batch is kept on disk and is just late, without one it is lost.
|
|
33
35
|
# * other 4xx: the drain will never accept this batch (unknown token, paused project, body too
|
|
34
36
|
# big). Retrying cannot help, so the batch is dropped and a warning says why.
|
|
35
|
-
# * 5xx, timeouts, connection errors:
|
|
37
|
+
# * 5xx, timeouts, connection errors: an outage. Count towards opening the circuit; the batch
|
|
38
|
+
# goes to the spool if there is one.
|
|
36
39
|
module Onlylogs
|
|
37
40
|
class HttpDevice
|
|
38
41
|
# The drain answered with a 4xx other than 429: the batch itself is the problem, not the drain.
|
|
@@ -85,6 +88,7 @@ module Onlylogs
|
|
|
85
88
|
read_timeout: ENV.fetch("ONLYLOGS_READ_TIMEOUT", DEFAULT_READ_TIMEOUT),
|
|
86
89
|
circuit_cooldown: ENV.fetch("ONLYLOGS_CIRCUIT_COOLDOWN", CIRCUIT_COOLDOWN),
|
|
87
90
|
keep_alive_timeout: ENV.fetch("ONLYLOGS_KEEP_ALIVE_TIMEOUT", DEFAULT_KEEP_ALIVE_TIMEOUT),
|
|
91
|
+
spool_enabled: ENV.fetch("ONLYLOGS_SPOOL_ENABLED", false),
|
|
88
92
|
spool_dir: ENV.fetch("ONLYLOGS_SPOOL_DIR", default_spool_dir),
|
|
89
93
|
spool_max_bytes: ENV.fetch("ONLYLOGS_SPOOL_MAX_BYTES", Spool::DEFAULT_MAX_BYTES)
|
|
90
94
|
)
|
|
@@ -99,6 +103,7 @@ module Onlylogs
|
|
|
99
103
|
@read_timeout = float_setting("ONLYLOGS_READ_TIMEOUT", read_timeout, DEFAULT_READ_TIMEOUT)
|
|
100
104
|
@circuit_cooldown = float_setting("ONLYLOGS_CIRCUIT_COOLDOWN", circuit_cooldown, CIRCUIT_COOLDOWN)
|
|
101
105
|
@keep_alive_timeout = float_setting("ONLYLOGS_KEEP_ALIVE_TIMEOUT", keep_alive_timeout, DEFAULT_KEEP_ALIVE_TIMEOUT)
|
|
106
|
+
@spool_enabled = boolean_setting("ONLYLOGS_SPOOL_ENABLED", spool_enabled, false)
|
|
102
107
|
@spool_dir = spool_dir
|
|
103
108
|
@spool_max_bytes = integer_setting("ONLYLOGS_SPOOL_MAX_BYTES", spool_max_bytes, Spool::DEFAULT_MAX_BYTES)
|
|
104
109
|
@supervisor_mutex = Mutex.new
|
|
@@ -159,6 +164,17 @@ module Onlylogs
|
|
|
159
164
|
value.nil? || value.to_s.strip.empty?
|
|
160
165
|
end
|
|
161
166
|
|
|
167
|
+
TRUTHY = %w[true 1 yes on].freeze
|
|
168
|
+
FALSY = %w[false 0 no off].freeze
|
|
169
|
+
|
|
170
|
+
def boolean_setting(name, value, default)
|
|
171
|
+
text = value.to_s.strip.downcase
|
|
172
|
+
return true if TRUTHY.include?(text)
|
|
173
|
+
return false if text.empty? || FALSY.include?(text)
|
|
174
|
+
|
|
175
|
+
fallback_setting(name, value, default, "true or false")
|
|
176
|
+
end
|
|
177
|
+
|
|
162
178
|
def integer_setting(name, value, default, min: 1)
|
|
163
179
|
number = Integer(value, exception: false)
|
|
164
180
|
return number if number && number >= min
|
|
@@ -230,7 +246,7 @@ module Onlylogs
|
|
|
230
246
|
@http_mutex = Mutex.new
|
|
231
247
|
@http = nil
|
|
232
248
|
@sender_thread = nil
|
|
233
|
-
@spool = build_spool(@spool_dir, @spool_max_bytes) if @drain_url
|
|
249
|
+
@spool = build_spool(@spool_dir, @spool_max_bytes) if @drain_url && @spool_enabled
|
|
234
250
|
@consecutive_failures = 0
|
|
235
251
|
@circuit_open_until = nil
|
|
236
252
|
@dropped = 0
|
|
@@ -326,8 +342,7 @@ module Onlylogs
|
|
|
326
342
|
body = lines.join("\n")
|
|
327
343
|
|
|
328
344
|
# Drain is known to be down: skip the request entirely so we don't block for the full read
|
|
329
|
-
# timeout on every batch.
|
|
330
|
-
# spool configured, spool_write is a no-op and the batch is dropped — best-effort logging).
|
|
345
|
+
# timeout on every batch. The batch is dropped, unless a spool is configured to keep it.
|
|
331
346
|
if circuit_open?
|
|
332
347
|
spool_write(body)
|
|
333
348
|
return
|
|
@@ -373,8 +388,9 @@ module Onlylogs
|
|
|
373
388
|
end
|
|
374
389
|
end
|
|
375
390
|
|
|
391
|
+
# A spool that cannot be set up must not stop the app from logging: it is disabled with a warning.
|
|
376
392
|
def build_spool(dir, max_bytes)
|
|
377
|
-
|
|
393
|
+
raise ArgumentError, "ONLYLOGS_SPOOL_DIR is empty" if blank?(dir)
|
|
378
394
|
|
|
379
395
|
Spool.new(dir: dir, max_bytes: max_bytes)
|
|
380
396
|
rescue => e
|
|
@@ -382,9 +398,8 @@ module Onlylogs
|
|
|
382
398
|
nil
|
|
383
399
|
end
|
|
384
400
|
|
|
385
|
-
#
|
|
386
|
-
#
|
|
387
|
-
# redeploys, or set it empty to disable.
|
|
401
|
+
# Under the app's tmp dir, which survives a drain outage while the app keeps running; point
|
|
402
|
+
# ONLYLOGS_SPOOL_DIR at a persistent volume to also survive redeploys.
|
|
388
403
|
def default_spool_dir
|
|
389
404
|
base = if defined?(Rails) && Rails.respond_to?(:root) && Rails.root
|
|
390
405
|
Rails.root.to_s
|
data/lib/onlylogs/version.rb
CHANGED
data/lib/onlylogs.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require "sqlite_shards"
|
|
1
2
|
require "onlylogs/version"
|
|
2
3
|
require "onlylogs/configuration"
|
|
3
4
|
require "onlylogs/engine"
|
|
@@ -18,6 +19,9 @@ require "onlylogs/http_logger"
|
|
|
18
19
|
# loader.setup
|
|
19
20
|
|
|
20
21
|
module Onlylogs
|
|
22
|
+
# Not autoloaded: referenced from class bodies (rescue_from, subclassing).
|
|
23
|
+
class Error < StandardError; end
|
|
24
|
+
|
|
21
25
|
class ForbiddenPathError < StandardError; end
|
|
22
26
|
|
|
23
27
|
if defined?(Importmap)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: onlylogs
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.12.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alessandro Rodi
|
|
@@ -23,6 +23,34 @@ dependencies:
|
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
25
|
version: '8.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: sqlite3
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '2.0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '2.0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: sqlite_shards
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '0.1'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '0.1'
|
|
26
54
|
description: This gem includes all the tools needed to view and stream you log files
|
|
27
55
|
directly on a web interface.
|
|
28
56
|
email:
|
|
@@ -49,15 +77,21 @@ files:
|
|
|
49
77
|
- app/assets/stylesheets/onlylogs/clusterize.css
|
|
50
78
|
- app/channels/onlylogs/application_cable/channel.rb
|
|
51
79
|
- app/channels/onlylogs/logs_channel.rb
|
|
80
|
+
- app/controllers/concerns/onlylogs/authentication.rb
|
|
52
81
|
- app/controllers/onlylogs/application_controller.rb
|
|
53
82
|
- app/controllers/onlylogs/logs_controller.rb
|
|
83
|
+
- app/controllers/onlylogs/queries_controller.rb
|
|
84
|
+
- app/controllers/onlylogs/viewer_controller.rb
|
|
54
85
|
- app/helpers/onlylogs/application_helper.rb
|
|
55
86
|
- app/javascript/onlylogs/application.js
|
|
56
87
|
- app/javascript/onlylogs/controllers/application.js
|
|
57
88
|
- app/javascript/onlylogs/controllers/auto_submit_controller.js
|
|
58
89
|
- app/javascript/onlylogs/controllers/index.js
|
|
59
90
|
- app/javascript/onlylogs/controllers/keyboard_shortcuts_controller.js
|
|
91
|
+
- app/javascript/onlylogs/controllers/log_cursor_controller.js
|
|
60
92
|
- app/javascript/onlylogs/controllers/log_streamer_controller.js
|
|
93
|
+
- app/javascript/onlylogs/controllers/match_highlight_controller.js
|
|
94
|
+
- app/javascript/onlylogs/controllers/queries_controller.js
|
|
61
95
|
- app/javascript/onlylogs/controllers/range_slider_controller.js
|
|
62
96
|
- app/javascript/onlylogs/controllers/text_selection_controller.js
|
|
63
97
|
- app/jobs/onlylogs/application_job.rb
|
|
@@ -66,6 +100,8 @@ files:
|
|
|
66
100
|
- app/models/onlylogs/file.rb
|
|
67
101
|
- app/models/onlylogs/file_path_parser.rb
|
|
68
102
|
- app/models/onlylogs/grep.rb
|
|
103
|
+
- app/models/onlylogs/queries_record.rb
|
|
104
|
+
- app/models/onlylogs/query.rb
|
|
69
105
|
- app/models/onlylogs/secure_file_path.rb
|
|
70
106
|
- app/views/home/show.html.erb
|
|
71
107
|
- app/views/layouts/onlylogs/application.html.erb
|
|
@@ -73,6 +109,7 @@ files:
|
|
|
73
109
|
- app/views/onlylogs/shared/_log_container.html.erb
|
|
74
110
|
- app/views/onlylogs/shared/_log_container_styles.html.erb
|
|
75
111
|
- app/views/onlylogs/shared/_range_slider.html.erb
|
|
112
|
+
- app/views/onlylogs/shared/_shortcuts_dialog.html.erb
|
|
76
113
|
- bin/onlylogs_sidecar
|
|
77
114
|
- bin/super_grep
|
|
78
115
|
- bin/super_ripgrep
|