I'm using Hera with Argo Workflows to run a workflow template that processes data and uploads results to S3. The workflow runs successfully, and I can retrieve artifact outputs by iterating through the workflow status nodes, but I can't figure out how to retrieve the step logs through Hera. The logs are available with kubectl logs, and my scripts currently use print statements so the output is human-readable. These tools are intended for data analysts who may need an explanation of what went wrong without dealing with Kubernetes directly. Is there a Python or Hera-native way to fetch the logs, or do I need to invoke kubectl behind the scenes?
3 Answers
Argo does not permanently retain pod logs by default. The usual approach is to write application output to stdout and use a cluster logging system such as Loki, Fluent Bit, or another centralized log collector. You can also enable Argo’s archived logs, but that is generally less capable than a dedicated logging platform.
If you’re trying to read the live pod logs through the workflow interface, check the Kubernetes permissions of the service account being used. The account needs permission to read pod logs, typically through an appropriate Role or ClusterRole and binding. The workflow can run successfully while log access still fails because those permissions are separate.
For a simple self-contained script, calling the Kubernetes pod-log API directly is more Pythonic than shelling out to kubectl. Once you identify the workflow node’s pod name and namespace, use the Kubernetes Python client’s read_namespaced_pod_log method, and make sure the script’s credentials have pods/log get permission. If you need logs after pods are deleted or want reliable historical access, use centralized logging or configure log archiving instead.

The output is already going to stdout, and kubectl logs can display it. I’m specifically looking for a Hera/Python method so less-technical users can receive the output directly. I’ve tried several methods resembling workflow_logs, but none have worked, so invoking kubectl as a fallback may be necessary.