Skip to content

Report Issue mail names a container log path that never exists when the spec uses container sharing #601

Description

@danielloader

Summary

When a spec uses container sharing (container-pre-initialization / seats), the "Report Issue" mail names a container log file that does not exist, and can never exist. The logs themselves are written correctly — only the path the mail reports is wrong. I would like to know whether this is an oversight or an accepted limitation of combining container sharing with proxy.container-log-path, before I offer a PR.

Environment

  • ShinyProxy 3.2.4 (containerproxy 1.2.4)
  • Kubernetes backend, 2 replicas, store-mode: Redis
  • proxy.container-log-path: s3://<bucket>/<prefix>/
  • The spec uses container sharing, with the app pods pre-initialized

What happens

A user reports an issue from a shared-seat app. The mail says:

AppId: 32a96d14-2dde-4839-895a-af3a581d2482
App: rating
Log (stdout): s3:/<bucket>/<prefix>/rating_32a96d14-2dde-4839-895a-af3a581d2482_15_Sep_2026_17_24_50_stdout.log
Log (stderr): s3:/<bucket>/<prefix>/rating_32a96d14-2dde-4839-895a-af3a581d2482_15_Sep_2026_17_24_50_stderr.log

Neither object exists (both HeadObject calls return 404), and no object anywhere in the bucket contains that proxy id. The log that does exist is:

<prefix>/rating_c827815f-7ce0-472f-8541-6d38dde033b9_15_Sep_2026_16_57_30_stdout.log

c827815f-… is the delegate proxy, which ShinyProxy itself logged when the seat was claimed:

ProxySharingDispatcher : [user=… proxyId=32a96d14-… specId=rating delegateProxyId=c827815f-… seatId=…] Seat claimed

It is also the pod that ran the app (sp-pod-c827815f-…-0), so the container, the pod and the log file all agree with each other — the mail is the only thing that disagrees.

Where it comes from, as far as I can tell

Two things combine:

  1. IssueController.sendSupportMail calls logService.getLogs(proxy) with the user-facing proxy, and AbstractLogStorage.getLogs derives both the cache key and the file name from proxy.getId(). But LogService attached the output for the delegate proxy, which is what owns the container, so the file was written under the delegate's id. The two ids can never coincide once a spec shares containers.
  2. The name embeds a timestamp minted lazily inside computeIfAbsent, so any instance that did not attach the output invents a fresh one. With more than one replica, the instance handling POST /issue is frequently not the instance that opened the file — the timestamp in the example above is the moment the user pressed the button, not the moment the log was opened.

For (1) it looks like Proxy#getTargetId() is already exactly the right value: DefaultProxyDispatcher sets TargetIdKey to the proxy's own id, and ProxySharingDispatcher sets it to the delegate proxy's id, so one accessor covers both cases without special-casing.

Related, and possibly intentional

On a filesystem container-log-path the mail attaches the log; on S3 it can only name it, because IssueController tests filePaths.getStdout().toFile().exists(), which an S3 key never satisfies. Is that also deliberate? If so, I understand the reasoning — but combined with the above, an operator receiving a support mail from a shared-seat app currently has no usable route from the mail to the logs.

Also minor: the path is printed as s3:/bucket/... with a single slash, because Paths.get normalises the // away.

Question

Is (1) a miss, or is container logging understood not to apply to shared containers? Same question for the multi-replica timestamp in (2).

If you would take patches, I am happy to open them — I would expect (1) to be a small change around getTargetId(), and (2) to need the resolved names carried on the proxy rather than recomputed. Glad to follow whatever shape you would prefer.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions