Skip to content

Commit bc65fa9

Browse files
committed
Add grep to get_logs
1 parent 7afd705 commit bc65fa9

2 files changed

Lines changed: 64 additions & 17 deletions

File tree

lib/tidewave/tools/get_logs.rb

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,20 @@ class Tidewave::Tools::GetLogs < Tidewave::Tools::Base
1010

1111
arguments do
1212
required(:tail).filled(:integer).description("The number of log entries to return from the end of the log")
13+
optional(:grep).filled(:string).description("Filter logs with the given regular expression (case insensitive). E.g. \"error\" when you want to capture errors in particular")
1314
end
1415

15-
def call(tail:)
16+
def call(tail:, grep: nil)
1617
log_file = Rails.root.join("log", "#{Rails.env}.log")
1718
return "Log file not found" unless File.exist?(log_file)
1819

19-
logs = File.readlines(log_file).last(tail)
20-
logs.join
20+
logs = File.readlines(log_file)
21+
22+
if grep
23+
regex = Regexp.new(grep, Regexp::IGNORECASE)
24+
logs = logs.select { |line| line.match?(regex) }
25+
end
26+
27+
logs.last(tail).join
2128
end
2229
end

spec/tools/get_logs_spec.rb

Lines changed: 54 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,65 @@
99
end
1010
end
1111

12-
describe ".description" do
13-
it "returns the correct description" do
14-
expect(described_class.description).to eq(
15-
<<~DESCRIPTION
16-
Returns all log output, excluding logs that were caused by other tool calls.
17-
18-
Use this tool to check for request logs or potentially logged errors.
19-
DESCRIPTION
20-
)
21-
end
22-
end
23-
2412
describe "#call" do
2513
let(:log_file_path) { "spec/fixtures/fake_development_log.log" }
2614
let(:log_file_content) { File.read(log_file_path) }
2715

28-
it "returns the correct logs" do
16+
before do
2917
allow(Rails).to receive_message_chain(:root, :join).and_return(Pathname.new(log_file_path))
30-
expect(described_class.new.call(tail: 10)).to eq(log_file_content.lines.last(10).join)
18+
end
19+
20+
context "without grep filter" do
21+
it "returns the correct logs" do
22+
expect(described_class.new.call(tail: 10)).to eq(log_file_content.lines.last(10).join)
23+
end
24+
25+
it "returns all lines when tail is larger than file" do
26+
total_lines = log_file_content.lines.count
27+
expect(described_class.new.call(tail: total_lines + 10)).to eq(log_file_content)
28+
end
29+
end
30+
31+
context "with grep filter" do
32+
it "filters logs with the given regular expression" do
33+
result = described_class.new.call(tail: 100, grep: "Never gonna")
34+
lines = result.lines
35+
36+
expect(lines.all? { |line| line.match?(/Never gonna/) }).to be true
37+
expect(lines.size).to be > 0
38+
end
39+
40+
it "respects tail limit after filtering" do
41+
result = described_class.new.call(tail: 3, grep: "Never gonna")
42+
lines = result.lines
43+
expect(lines.size).to eq(3)
44+
end
45+
46+
it "works with case-insensitive regex" do
47+
result = described_class.new.call(tail: 100, grep: "NEVER GONNA")
48+
lines = result.lines
49+
50+
expect(lines.all? { |line| line.match?(/Never gonna/i) }).to be true
51+
expect(lines.size).to be > 0
52+
end
53+
54+
it "works with complex regex patterns" do
55+
result = described_class.new.call(tail: 100, grep: "never gonna (give|let)")
56+
lines = result.lines
57+
58+
expect(lines.all? { |line| line.match?(/Never gonna (give|let)/i) }).to be true
59+
expect(lines.size).to be > 0
60+
end
61+
end
62+
63+
context "when log file doesn't exist" do
64+
before do
65+
allow(Rails).to receive_message_chain(:root, :join).and_return(Pathname.new("nonexistent.log"))
66+
end
67+
68+
it "returns appropriate message" do
69+
expect(described_class.new.call(tail: 10)).to eq("Log file not found")
70+
end
3171
end
3272
end
3373
end

0 commit comments

Comments
 (0)