Skip to content

Conversation

@ericfeunekes
Copy link

Changes

  • Add the databricks apps logs NAME command, including tail/follow/search/source/output-file flags wired via cmdgroup, file mirroring with 0600 perms, and validation against apps that lack a public URL. (cmd/workspace/apps)
  • Introduce the reusable libs/logstream helper with token refresh hooks, buffering, search/source filtering, structured error handling, context-driven deadlines, and a comprehensive unit suite so other commands can stream logs without bespoke WebSocket loops.
  • Refactor databricks auth token to reuse auth.AcquireToken via the new libs/auth/token_loader.go, ensuring persistent auth options and timeouts stay centralized and fully covered by regression tests.

Why

This is a quality of life addition that allows the CLI to tail logs to the CLI. It hooks directly into the token acquisition module so that the tokens don't need to be managed separately.

Tests

  • go test ./libs/logstream
  • go test ./cmd/workspace/apps
  • go test ./cmd/auth

Copy link
Member

@pkosiec pkosiec left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @ericfeunekes for your contribution! The new app logs command is super helpful. I tested the changes and it works well 👍

Before merge, please take a look at my comments. I can help you implementing the changes if you'd like to - feel free to ping me anytime. Thanks!

@ericfeunekes
Copy link
Author

ericfeunekes commented Nov 13, 2025

@pkosiec I think I've addressed each of your issues and tried to keep them on separate commits to make it easier to review

@pkosiec pkosiec self-assigned this Nov 14, 2025
Copy link
Member

@pkosiec pkosiec left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for implementing the comments, including the logs color formatting!

Image

We're almost there - I put some minor comments. There's one small issue with -f and -tail-lines flags, but other than that I don't see any major blockers 👍

Copy link
Contributor

@pietern pietern left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @ericfeunekes, thanks for the PR!

The token changes (cmd/auth/token_* and libs/auth/token_*) are not necessary. You can use the TokenSource function on the SDK configuration directly to get a fresh OAuth token. I confirmed that the following patch works: https://gist.github.com/pietern/41d02acc2907416244789c7408fb232f

Please move logstream to libs/apps to make it clearer that it is specific to apps.

@pietern
Copy link
Contributor

pietern commented Nov 17, 2025

Btw, when I stop an app during tail, the logs command doesn't stop or error.

@pietern
Copy link
Contributor

pietern commented Nov 17, 2025

@ericfeunekes I forgot an important detail in the previous message.

Contributing to CLI requires a signed CLA, if that's something you're willing to do, please reach out with a request to sign CLA to [email protected] and we will take it from there.

Thanks!

Eric Feunekes and others added 9 commits November 18, 2025 09:43
Replace custom token acquisition logic with SDK's built-in TokenSource
function as suggested by @pietern. This simplifies the implementation
by delegating token lifecycle management to the SDK configuration.

Changes:
- Use cfg.GetTokenSource() instead of auth.AcquireToken()
- Remove custom token_loader abstraction (libs/auth/token_loader.go)
- Revert cmd/auth/token.go to original implementation
- Remove tokenAcquireTimeout constant (handled by SDK)

This addresses review feedback from @pietern on Nov 17, 2025.
Reference: https://gist.github.com/pietern/41d02acc2907416244789c7408fb232f

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Relocate logstream from libs/logstream to libs/apps/logstream to make
it clearer that this package is specific to Databricks Apps functionality.

Changes:
- Move libs/logstream/streamer.go to libs/apps/logstream/streamer.go
- Move libs/logstream/streamer_test.go to libs/apps/logstream/streamer_test.go
- Update import in cmd/workspace/apps/logs.go

This addresses review feedback from @pietern on Nov 17, 2025.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Group individual const declarations into a single const block for better
code organization and readability.

Changes:
- Convert six individual const declarations to const block
- Apply alignment formatting

This addresses review feedback from @pkosiec on Nov 14, 2025.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
When using --tail-lines with -f (follow), the buffer was flushing too
early, showing all historical logs instead of just the last N lines.

The tail buffer maintains a rolling window of the last N lines, but it
was flushing as soon as it reached N lines when following, rather than
waiting for the prefetch window to collect all historical logs first.

Fix: Always respect the flush deadline (prefetch window) regardless of
follow mode. This allows historical logs to stream in and the rolling
buffer to maintain only the truly last N lines before flushing.

Example with --tail-lines 10 -f:
- Before: Shows lines 1-10, then 11-1000+ (all logs)
- After: Shows lines 991-1000, then new logs (correct)

This addresses review feedback from @pkosiec on Nov 14, 2025.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
Replace magic number (30 seconds) with defaultHandshakeTimeout constant
for better code maintainability.

Changes:
- Add defaultHandshakeTimeout = 30 * time.Second to const block
- Use constant in newLogStreamDialer instead of inline value

This addresses review feedback from @pkosiec on Nov 12/14, 2025.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@ericfeunekes ericfeunekes requested a review from a team as a code owner November 18, 2025 15:05
Eric Feunekes and others added 3 commits November 18, 2025 12:36
When following app logs (--follow) and the app stops or is deleted,
the logs command now detects this and exits gracefully instead of
retrying indefinitely.

Implementation:
- Added AppStatusChecker callback to logstream.Config
- Check app status before each reconnect attempt in follow mode
- Also check when connection closes normally during follow
- Exit with clear error message when app is stopped/deleting/error state

This addresses @pietern's comment about the command not stopping when
the app is stopped during tail.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@github-actions
Copy link

github-actions bot commented Dec 2, 2025

An authorized user can trigger integration tests manually by following the instructions below:

Trigger:
go/deco-tests-run/cli

Inputs:

  • PR number: 3908
  • Commit SHA: 06aece03b0b3f73138e0eb20e6720d5fc4315c2c

Checks will be approved automatically on success.

@andrewnester andrewnester removed the request for review from a team December 2, 2025 16:10
@pietern
Copy link
Contributor

pietern commented Dec 3, 2025

@ericfeunekes Can you update the PR summary to match the current state of the PR?

@eng-dev-ecosystem-bot
Copy link
Collaborator

eng-dev-ecosystem-bot commented Dec 3, 2025

Commit: 06aece0

Run: 19887153901

Env 🟨​KNOWN 🔄​flaky 💚​RECOVERED 🙈​SKIP ✅​pass 🙈​skip Time
🟨​ aws linux 7 2 371 637 17:30
🟨​ aws windows 7 2 2 371 635 17:33
💚​ aws-ucws linux 7 2 514 522 21:01
💚​ aws-ucws windows 7 2 516 520 18:24
💚​ azure linux 1 4 371 636 15:36
💚​ azure windows 1 4 373 634 22:50
💚​ azure-ucws linux 1 4 510 521 29:08
💚​ azure-ucws windows 1 4 512 519 18:23
💚​ gcp linux 1 4 364 640 15:18
💚​ gcp windows 1 4 366 638 16:38
11 failing tests:
Test Name aws linux aws windows aws-ucws linux aws-ucws windows azure linux azure windows azure-ucws linux azure-ucws windows gcp linux gcp windows
🟨​ TestAccept 🟨​K 🟨​K 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
🙈​ TestAccept/bundle/resources/permissions 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions 🟨​K 🟨​K 💚​R 💚​R 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions/DATABRICKS_BUNDLE_ENGINE=direct 🟨​K 🟨​K 💚​R 💚​R
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/with_permissions/DATABRICKS_BUNDLE_ENGINE=terraform 🟨​K 🟨​K 💚​R 💚​R
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions 🟨​K 🟨​K 💚​R 💚​R 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=direct 🟨​K 🟨​K 💚​R 💚​R
🟨​ TestAccept/bundle/resources/permissions/jobs/destroy_without_mgmtperms/without_permissions/DATABRICKS_BUNDLE_ENGINE=terraform 🟨​K 🟨​K 💚​R 💚​R
🙈​ TestAccept/bundle/run/app-with-job 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S 🙈​S
🔄​ TestAccept/bundle/templates/default-python/integration_classic ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p
🔄​ TestAccept/bundle/templates/default-python/integration_classic/DATABRICKS_BUNDLE_ENGINE=terraform/UV_PYTHON=3.11 ✅​p 🔄​f ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p ✅​p
Top 30 slowest tests (at least 2 minutes):
duration env testname
10:43 azure windows TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=terraform
10:37 azure windows TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=direct
9:43 azure-ucws linux TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=terraform
9:23 azure-ucws linux TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=direct
5:56 gcp linux TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=terraform
5:46 aws-ucws windows TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=direct
5:35 aws-ucws linux TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=direct
5:33 gcp windows TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=terraform
5:32 aws-ucws windows TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=terraform
5:30 aws linux TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=terraform
5:29 aws-ucws linux TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=terraform
5:18 aws linux TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=direct
5:15 gcp linux TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=direct
5:15 aws windows TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=terraform
5:14 aws-ucws linux TestAccept/ssh/connection
4:45 gcp windows TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=direct
4:35 azure-ucws windows TestSecretsPutSecretStringValue
4:15 azure-ucws linux TestAccept/ssh/connection
3:55 azure linux TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=direct
3:51 azure linux TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=terraform
3:43 azure-ucws windows TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=direct
3:32 azure-ucws windows TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=terraform
3:22 azure-ucws linux TestAccept/bundle/resources/synced_database_tables/basic
3:15 azure-ucws windows TestAccept/ssh/connection
3:07 gcp linux TestAccept/ssh/connection
2:36 azure-ucws windows TestAccept/bundle/resources/synced_database_tables/basic
2:27 aws windows TestAccept/bundle/resources/clusters/deploy/update-after-create/DATABRICKS_BUNDLE_ENGINE=direct
2:16 aws linux TestAccept/ssh/connection
2:04 azure linux TestAccept/ssh/connection
2:00 aws linux TestSecretsPutSecretStringValue

@pietern
Copy link
Contributor

pietern commented Dec 3, 2025

@ericfeunekes Thanks for signing the CLA. This PR can proceed.

Can you update the PR summary to match the current state of the PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants