From 384b36d158550cc0754f7f11478036b232786f2b Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 20 Sep 2024 07:42:31 -0700 Subject: [PATCH 1/8] Add option to skip timestamps on logging output So it is easier to follow live when you are doing debugging, especially early days app setup when you are the only user. --- lib/kamal/cli/accessory.rb | 8 +++++--- lib/kamal/cli/app.rb | 8 +++++--- lib/kamal/cli/proxy.rb | 8 +++++--- lib/kamal/commands/accessory.rb | 8 ++++---- lib/kamal/commands/app/logging.rb | 4 ++-- lib/kamal/commands/proxy.rb | 10 ++++++---- test/commands/accessory_test.rb | 8 ++++++++ test/commands/app_test.rb | 4 ++++ test/commands/proxy_test.rb | 6 ++++++ 9 files changed, 45 insertions(+), 19 deletions(-) diff --git a/lib/kamal/cli/accessory.rb b/lib/kamal/cli/accessory.rb index dd56231e5..45efbe6e6 100644 --- a/lib/kamal/cli/accessory.rb +++ b/lib/kamal/cli/accessory.rb @@ -147,23 +147,25 @@ def exec(name, cmd) option :grep, aliases: "-g", desc: "Show lines with grep match only (use this to fetch specific requests by id)" option :grep_options, aliases: "-o", desc: "Additional options supplied to grep" option :follow, aliases: "-f", desc: "Follow logs on primary server (or specific host set by --hosts)" + option :skip_timestamps, aliases: "-T", desc: "Skip appending timestamps to logging output" def logs(name) with_accessory(name) do |accessory, hosts| grep = options[:grep] grep_options = options[:grep_options] + timestamps = !options[:skip_timestamps] if options[:follow] run_locally do info "Following logs on #{hosts}..." - info accessory.follow_logs(grep: grep, grep_options: grep_options) - exec accessory.follow_logs(grep: grep, grep_options: grep_options) + info accessory.follow_logs(timestamps: timestamps, grep: grep, grep_options: grep_options) + exec accessory.follow_logs(timestamps: timestamps, grep: grep, grep_options: grep_options) end else since = options[:since] lines = options[:lines].presence || ((since || grep) ? nil : 100) # Default to 100 lines if since or grep isn't set on(hosts) do - puts capture_with_info(*accessory.logs(since: since, lines: lines, grep: grep, grep_options: grep_options)) + puts capture_with_info(*accessory.logs(timestamps: timestamps, since: since, lines: lines, grep: grep, grep_options: grep_options)) end end end diff --git a/lib/kamal/cli/app.rb b/lib/kamal/cli/app.rb index d70d066b4..2382951dc 100644 --- a/lib/kamal/cli/app.rb +++ b/lib/kamal/cli/app.rb @@ -188,12 +188,14 @@ def images option :grep, aliases: "-g", desc: "Show lines with grep match only (use this to fetch specific requests by id)" option :grep_options, aliases: "-o", desc: "Additional options supplied to grep" option :follow, aliases: "-f", desc: "Follow log on primary server (or specific host set by --hosts)" + option :skip_timestamps, aliases: "-T", desc: "Skip appending timestamps to logging output" def logs # FIXME: Catch when app containers aren't running grep = options[:grep] grep_options = options[:grep_options] since = options[:since] + timestamps = !options[:skip_timestamps] if options[:follow] lines = options[:lines].presence || ((since || grep) ? nil : 10) # Default to 10 lines if since or grep isn't set @@ -205,8 +207,8 @@ def logs role = KAMAL.roles_on(KAMAL.primary_host).first app = KAMAL.app(role: role, host: host) - info app.follow_logs(host: KAMAL.primary_host, lines: lines, grep: grep, grep_options: grep_options) - exec app.follow_logs(host: KAMAL.primary_host, lines: lines, grep: grep, grep_options: grep_options) + info app.follow_logs(host: KAMAL.primary_host, timestamps: timestamps, lines: lines, grep: grep, grep_options: grep_options) + exec app.follow_logs(host: KAMAL.primary_host, timestamps: timestamps, lines: lines, grep: grep, grep_options: grep_options) end else lines = options[:lines].presence || ((since || grep) ? nil : 100) # Default to 100 lines if since or grep isn't set @@ -216,7 +218,7 @@ def logs roles.each do |role| begin - puts_by_host host, capture_with_info(*KAMAL.app(role: role, host: host).logs(since: since, lines: lines, grep: grep, grep_options: grep_options)) + puts_by_host host, capture_with_info(*KAMAL.app(role: role, host: host).logs(timestamps: timestamps, since: since, lines: lines, grep: grep, grep_options: grep_options)) rescue SSHKit::Command::Failed puts_by_host host, "Nothing found" end diff --git a/lib/kamal/cli/proxy.rb b/lib/kamal/cli/proxy.rb index d006c8c6f..0fc595b0c 100644 --- a/lib/kamal/cli/proxy.rb +++ b/lib/kamal/cli/proxy.rb @@ -140,21 +140,23 @@ def details option :lines, type: :numeric, aliases: "-n", desc: "Number of log lines to pull from each server" option :grep, aliases: "-g", desc: "Show lines with grep match only (use this to fetch specific requests by id)" option :follow, aliases: "-f", desc: "Follow logs on primary server (or specific host set by --hosts)" + option :skip_timestamps, aliases: "-T", desc: "Skip appending timestamps to logging output" def logs grep = options[:grep] + timestamps = !options[:skip_timestamps] if options[:follow] run_locally do info "Following logs on #{KAMAL.primary_host}..." - info KAMAL.proxy.follow_logs(host: KAMAL.primary_host, grep: grep) - exec KAMAL.proxy.follow_logs(host: KAMAL.primary_host, grep: grep) + info KAMAL.proxy.follow_logs(host: KAMAL.primary_host, timestamps: timestamps, grep: grep) + exec KAMAL.proxy.follow_logs(host: KAMAL.primary_host, timestamps: timestamps, grep: grep) end else since = options[:since] lines = options[:lines].presence || ((since || grep) ? nil : 100) # Default to 100 lines if since or grep isn't set on(KAMAL.proxy_hosts) do |host| - puts_by_host host, capture(*KAMAL.proxy.logs(since: since, lines: lines, grep: grep)), type: "Proxy" + puts_by_host host, capture(*KAMAL.proxy.logs(timestamps: timestamps, since: since, lines: lines, grep: grep)), type: "Proxy" end end end diff --git a/lib/kamal/commands/accessory.rb b/lib/kamal/commands/accessory.rb index 787f7d43a..0c1b9009c 100644 --- a/lib/kamal/commands/accessory.rb +++ b/lib/kamal/commands/accessory.rb @@ -39,16 +39,16 @@ def info end - def logs(since: nil, lines: nil, grep: nil, grep_options: nil) + def logs(timestamps: true, since: nil, lines: nil, grep: nil, grep_options: nil) pipe \ - docker(:logs, service_name, (" --since #{since}" if since), (" --tail #{lines}" if lines), "--timestamps", "2>&1"), + docker(:logs, service_name, (" --since #{since}" if since), (" --tail #{lines}" if lines), ("--timestamps" if timestamps), "2>&1"), ("grep '#{grep}'#{" #{grep_options}" if grep_options}" if grep) end - def follow_logs(grep: nil, grep_options: nil) + def follow_logs(timestamps: true, grep: nil, grep_options: nil) run_over_ssh \ pipe \ - docker(:logs, service_name, "--timestamps", "--tail", "10", "--follow", "2>&1"), + docker(:logs, service_name, ("--timestamps" if timestamps), "--tail", "10", "--follow", "2>&1"), (%(grep "#{grep}"#{" #{grep_options}" if grep_options}) if grep) end diff --git a/lib/kamal/commands/app/logging.rb b/lib/kamal/commands/app/logging.rb index be8a4bad7..31b1981e6 100644 --- a/lib/kamal/commands/app/logging.rb +++ b/lib/kamal/commands/app/logging.rb @@ -6,11 +6,11 @@ def logs(version: nil, since: nil, lines: nil, grep: nil, grep_options: nil) ("grep '#{grep}'#{" #{grep_options}" if grep_options}" if grep) end - def follow_logs(host:, lines: nil, grep: nil, grep_options: nil) + def follow_logs(host:, timestamps: true, lines: nil, grep: nil, grep_options: nil) run_over_ssh \ pipe( current_running_container_id, - "xargs docker logs --timestamps#{" --tail #{lines}" if lines} --follow 2>&1", + "xargs docker logs #{"--timestamps" if timestamps}#{" --tail #{lines}" if lines} --follow 2>&1", (%(grep "#{grep}"#{" #{grep_options}" if grep_options}) if grep) ), host: host diff --git a/lib/kamal/commands/proxy.rb b/lib/kamal/commands/proxy.rb index df264a6b3..90d03141c 100644 --- a/lib/kamal/commands/proxy.rb +++ b/lib/kamal/commands/proxy.rb @@ -35,15 +35,17 @@ def version [ :cut, "-d:", "-f2" ] end - def logs(since: nil, lines: nil, grep: nil, grep_options: nil) + def logs(timestamps: true, since: nil, lines: nil, grep: nil, grep_options: nil) pipe \ - docker(:logs, container_name, (" --since #{since}" if since), (" --tail #{lines}" if lines), "--timestamps", "2>&1"), + docker(:logs, container_name, (" --since #{since}" if since), (" --tail #{lines}" if lines), ("--timestamps" if timestamps), "2>&1"), ("grep '#{grep}'#{" #{grep_options}" if grep_options}" if grep) end - def follow_logs(host:, grep: nil, grep_options: nil) + def follow_logs(host:, timestamps: true, grep: nil, grep_options: nil) run_over_ssh pipe( - docker(:logs, container_name, "--timestamps", "--tail", "10", "--follow", "2>&1"), + docker(:logs, container_name), + ("--timestamps" if timestamps), + "--tail", "10", "--follow", "2>&1"), (%(grep "#{grep}"#{" #{grep_options}" if grep_options}) if grep) ).join(" "), host: host end diff --git a/test/commands/accessory_test.rb b/test/commands/accessory_test.rb index 19fe745d8..f3d71ffd3 100644 --- a/test/commands/accessory_test.rb +++ b/test/commands/accessory_test.rb @@ -130,12 +130,20 @@ class CommandsAccessoryTest < ActiveSupport::TestCase assert_equal \ "docker logs app-mysql --since 5m --tail 100 --timestamps 2>&1 | grep 'thing' -C 2", new_command(:mysql).logs(since: "5m", lines: 100, grep: "thing", grep_options: "-C 2").join(" ") + + assert_equal \ + "docker logs app-mysql --since 5m --tail 100 2>&1 | grep 'thing' -C 2", + new_command(:mysql).logs(timestamps: false, since: "5m", lines: 100, grep: "thing", grep_options: "-C 2").join(" ") end test "follow logs" do assert_equal \ "ssh -t root@1.1.1.5 -p 22 'docker logs app-mysql --timestamps --tail 10 --follow 2>&1'", new_command(:mysql).follow_logs + + assert_equal \ + "ssh -t root@1.1.1.5 -p 22 'docker logs app-mysql --tail 10 --follow 2>&1'", + new_command(:mysql).follow_logs(timestamps: false) end test "remove container" do diff --git a/test/commands/app_test.rb b/test/commands/app_test.rb index 57f8c2fe3..23dd6c861 100644 --- a/test/commands/app_test.rb +++ b/test/commands/app_test.rb @@ -191,6 +191,10 @@ class CommandsAppTest < ActiveSupport::TestCase assert_equal \ "ssh -t root@app-1 -p 22 'sh -c '\\''docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''\\'\\'''\\''{{.ID}}'\\''\\'\\'''\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting'\\'' | head -1 | xargs docker logs --timestamps --tail 123 --follow 2>&1 | grep \"Completed\"'", new_command.follow_logs(host: "app-1", lines: 123, grep: "Completed") + + assert_equal \ + "ssh -t root@app-1 -p 22 'sh -c '\\''docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''\\'\\'''\\''{{.ID}}'\\''\\'\\'''\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting'\\'' | head -1 | xargs docker logs --tail 123 --follow 2>&1 | grep \"Completed\"'", + new_command.follow_logs(host: "app-1", timestamps: false, lines: 123, grep: "Completed") end diff --git a/test/commands/proxy_test.rb b/test/commands/proxy_test.rb index 4a4e029e2..4f6275a24 100644 --- a/test/commands/proxy_test.rb +++ b/test/commands/proxy_test.rb @@ -77,6 +77,12 @@ class CommandsProxyTest < ActiveSupport::TestCase new_command.logs(lines: 10).join(" ") end + test "proxy logs without timestamps" do + assert_equal \ + "docker logs kamal-proxy 2>&1", + new_command.logs(timestamps: false).join(" ") + end + test "proxy logs with grep hello!" do assert_equal \ "docker logs kamal-proxy --timestamps 2>&1 | grep 'hello!'", From afa6898a82b374dfd1e9b07edea6ca9d0b4b5863 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 20 Sep 2024 07:58:38 -0700 Subject: [PATCH 2/8] Fix pipe --- lib/kamal/commands/proxy.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/kamal/commands/proxy.rb b/lib/kamal/commands/proxy.rb index 90d03141c..9b145d2da 100644 --- a/lib/kamal/commands/proxy.rb +++ b/lib/kamal/commands/proxy.rb @@ -43,9 +43,7 @@ def logs(timestamps: true, since: nil, lines: nil, grep: nil, grep_options: nil) def follow_logs(host:, timestamps: true, grep: nil, grep_options: nil) run_over_ssh pipe( - docker(:logs, container_name), - ("--timestamps" if timestamps), - "--tail", "10", "--follow", "2>&1"), + docker(:logs, container_name, ("--timestamps" if timestamps), "--tail", "10", "--follow", "2>&1"), (%(grep "#{grep}"#{" #{grep_options}" if grep_options}) if grep) ).join(" "), host: host end From 6ab5fc9459bd42af4bd4e0d3d09b58fc856cc0b3 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 20 Sep 2024 08:04:28 -0700 Subject: [PATCH 3/8] Allow timestamps on/off for app logging too --- lib/kamal/commands/app/logging.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/kamal/commands/app/logging.rb b/lib/kamal/commands/app/logging.rb index 31b1981e6..ad66f370c 100644 --- a/lib/kamal/commands/app/logging.rb +++ b/lib/kamal/commands/app/logging.rb @@ -1,8 +1,8 @@ module Kamal::Commands::App::Logging - def logs(version: nil, since: nil, lines: nil, grep: nil, grep_options: nil) + def logs(version: nil, timestamps: true, since: nil, lines: nil, grep: nil, grep_options: nil) pipe \ version ? container_id_for_version(version) : current_running_container_id, - "xargs docker logs#{" --since #{since}" if since}#{" --tail #{lines}" if lines} 2>&1", + "xargs docker logs#{" --timestamps" if timestamps}#{" --since #{since}" if since}#{" --tail #{lines}" if lines} 2>&1", ("grep '#{grep}'#{" #{grep_options}" if grep_options}" if grep) end @@ -10,7 +10,7 @@ def follow_logs(host:, timestamps: true, lines: nil, grep: nil, grep_options: ni run_over_ssh \ pipe( current_running_container_id, - "xargs docker logs #{"--timestamps" if timestamps}#{" --tail #{lines}" if lines} --follow 2>&1", + "xargs docker logs#{" --timestamps" if timestamps}#{" --tail #{lines}" if lines} --follow 2>&1", (%(grep "#{grep}"#{" #{grep_options}" if grep_options}) if grep) ), host: host From 8693e968c1d5565746dc8a2fc70ecdd5a59e82ec Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 20 Sep 2024 08:17:19 -0700 Subject: [PATCH 4/8] Timestamps now default on for app logs too --- test/commands/app_test.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/commands/app_test.rb b/test/commands/app_test.rb index 23dd6c861..dc28ba57b 100644 --- a/test/commands/app_test.rb +++ b/test/commands/app_test.rb @@ -129,25 +129,25 @@ class CommandsAppTest < ActiveSupport::TestCase test "logs" do assert_equal \ - "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs 2>&1", + "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs --timestamps 2>&1", new_command.logs.join(" ") end test "logs with since" do assert_equal \ - "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs --since 5m 2>&1", + "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs --timestamps --since 5m 2>&1", new_command.logs(since: "5m").join(" ") end test "logs with lines" do assert_equal \ - "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs --tail 100 2>&1", + "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs --timestamps --tail 100 2>&1", new_command.logs(lines: "100").join(" ") end test "logs with since and lines" do assert_equal \ - "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs --since 5m --tail 100 2>&1", + "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs --timestamps --since 5m --tail 100 2>&1", new_command.logs(since: "5m", lines: "100").join(" ") end From d98500982d98d80a122b42c223e4dc1052068ee7 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 20 Sep 2024 08:19:38 -0700 Subject: [PATCH 5/8] Update tests --- test/cli/app_test.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/cli/app_test.rb b/test/cli/app_test.rb index 97e1c4615..7c208da20 100644 --- a/test/cli/app_test.rb +++ b/test/cli/app_test.rb @@ -315,11 +315,11 @@ class CliAppTest < CliTestCase SSHKit::Backend::Abstract.any_instance.stubs(:exec) .with("ssh -t root@1.1.1.1 'sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1| xargs docker logs --timestamps --tail 10 2>&1'") - assert_match "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs --tail 100 2>&1", run_command("logs") + assert_match "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs --timestamps --tail 100 2>&1", run_command("logs") - assert_match "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs 2>&1 | grep 'hey'", run_command("logs", "--grep", "hey") + assert_match "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs --timestamps 2>&1 | grep 'hey'", run_command("logs", "--grep", "hey") - assert_match "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs 2>&1 | grep 'hey' -C 2", run_command("logs", "--grep", "hey", "--grep-options", "-C 2") + assert_match "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs --timestamps 2>&1 | grep 'hey' -C 2", run_command("logs", "--grep", "hey", "--grep-options", "-C 2") end test "logs with follow" do From 487f6f5f5358c79544e5abde0303ce39b14f2fa9 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 20 Sep 2024 08:31:56 -0700 Subject: [PATCH 6/8] Fix excess spacing --- lib/kamal/commands/proxy.rb | 2 +- test/commands/proxy_test.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/kamal/commands/proxy.rb b/lib/kamal/commands/proxy.rb index 9b145d2da..5ac1c94e4 100644 --- a/lib/kamal/commands/proxy.rb +++ b/lib/kamal/commands/proxy.rb @@ -37,7 +37,7 @@ def version def logs(timestamps: true, since: nil, lines: nil, grep: nil, grep_options: nil) pipe \ - docker(:logs, container_name, (" --since #{since}" if since), (" --tail #{lines}" if lines), ("--timestamps" if timestamps), "2>&1"), + docker(:logs, container_name, ("--since #{since}" if since), ("--tail #{lines}" if lines), ("--timestamps" if timestamps), "2>&1"), ("grep '#{grep}'#{" #{grep_options}" if grep_options}" if grep) end diff --git a/test/commands/proxy_test.rb b/test/commands/proxy_test.rb index 4f6275a24..e8a3f2529 100644 --- a/test/commands/proxy_test.rb +++ b/test/commands/proxy_test.rb @@ -67,19 +67,19 @@ class CommandsProxyTest < ActiveSupport::TestCase test "proxy logs since 2h" do assert_equal \ - "docker logs kamal-proxy --since 2h --timestamps 2>&1", + "docker logs kamal-proxy --since 2h --timestamps 2>&1", new_command.logs(since: "2h").join(" ") end test "proxy logs last 10 lines" do assert_equal \ - "docker logs kamal-proxy --tail 10 --timestamps 2>&1", + "docker logs kamal-proxy --tail 10 --timestamps 2>&1", new_command.logs(lines: 10).join(" ") end test "proxy logs without timestamps" do assert_equal \ - "docker logs kamal-proxy 2>&1", + "docker logs kamal-proxy 2>&1", new_command.logs(timestamps: false).join(" ") end From eabd57350cf3f465396f7837cbbaf8a1da9cb6a5 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 20 Sep 2024 08:33:14 -0700 Subject: [PATCH 7/8] Fix tests --- test/commands/app_test.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/commands/app_test.rb b/test/commands/app_test.rb index dc28ba57b..6704adb63 100644 --- a/test/commands/app_test.rb +++ b/test/commands/app_test.rb @@ -153,25 +153,25 @@ class CommandsAppTest < ActiveSupport::TestCase test "logs with grep" do assert_equal \ - "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs 2>&1 | grep 'my-id'", + "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs --timestamps 2>&1 | grep 'my-id'", new_command.logs(grep: "my-id").join(" ") end test "logs with grep and grep options" do assert_equal \ - "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs 2>&1 | grep 'my-id' -C 2", + "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs --timestamps 2>&1 | grep 'my-id' -C 2", new_command.logs(grep: "my-id", grep_options: "-C 2").join(" ") end test "logs with since, grep and grep options" do assert_equal \ - "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs --since 5m 2>&1 | grep 'my-id' -C 2", + "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs --timestamps --since 5m 2>&1 | grep 'my-id' -C 2", new_command.logs(since: "5m", grep: "my-id", grep_options: "-C 2").join(" ") end test "logs with since and grep" do assert_equal \ - "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs --since 5m 2>&1 | grep 'my-id'", + "sh -c 'docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting --filter ancestor=$(docker image ls --filter reference=dhh/app:latest --format '\\''{{.ID}}'\\'') ; docker ps --latest --quiet --filter label=service=app --filter label=role=web --filter status=running --filter status=restarting' | head -1 | xargs docker logs --timestamps --since 5m 2>&1 | grep 'my-id'", new_command.logs(since: "5m", grep: "my-id").join(" ") end From 04d21f45bbe1f0a791ef33c90323f7f7d61a260a Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 20 Sep 2024 08:45:40 -0700 Subject: [PATCH 8/8] Fix test --- test/cli/proxy_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cli/proxy_test.rb b/test/cli/proxy_test.rb index 72a0aa13b..c9987a51a 100644 --- a/test/cli/proxy_test.rb +++ b/test/cli/proxy_test.rb @@ -111,11 +111,11 @@ class CliProxyTest < CliTestCase test "logs" do SSHKit::Backend::Abstract.any_instance.stubs(:capture) - .with(:docker, :logs, "kamal-proxy", " --tail 100", "--timestamps", "2>&1") + .with(:docker, :logs, "kamal-proxy", "--tail 100", "--timestamps", "2>&1") .returns("Log entry") SSHKit::Backend::Abstract.any_instance.stubs(:capture) - .with(:docker, :logs, "proxy", " --tail 100", "--timestamps", "2>&1") + .with(:docker, :logs, "proxy", "--tail 100", "--timestamps", "2>&1") .returns("Log entry") run_command("logs").tap do |output|