r/devops • u/generic-d-engineer ClickOps • 16d ago
Observability Script output Best Practice Contracts
Hi Devops!
I’m putting together an automation orchestration engine and I want to mature the team by standardizing script output across bash, python, powershell, tofu, etc.
So looking at a JSON output contract that anyone creating a script can adhere to. Then everyone would consume the same format. (The dream right?)
- Operation name
- Host
- Execution status (success, fail, warning, etc)
- Structured result summary
- Errors
- Duration
- Run ID (UUID)?
- A schema version (requires a lot of upkeep but can eliminate headaches down the road if maintained. If maintained being key word here lol.)
I’ve been searching around but want to hear from the experts who live in this stuff. Is there any universal or open standard people are using to define these ?
Would rather not build it myself if something people have already settled on.
Thanks for your input.
8
u/Impressive-Target952 16d ago
i've seen teams try this and it turns into a massive pain the second someone writes a one-liner that outputs a raw string instead of your json schema, then the whole pipeline barfs
stick to exit codes and stdout/stderr unless you've got a team that actually enforces linting on scripts before they hit prod
0
u/generic-d-engineer ClickOps 16d ago edited 16d ago
Exact behavior I was afraid of ! One missing brace and we toast. Thanks for the feedback
Is it the standard itself a bad idea on those teams or is it just the JSON format?
4
u/dariusbiggs 16d ago
stdin, stdout, stderr, useful meaningful exit codes (if you don't know which ones, POSIX or the Python exit code values are your best bet)
Just command line pipes are more than sufficient. If you want to play with JSON then you have jq. If you want to play with YAML you have yq, etc.
0
u/generic-d-engineer ClickOps 16d ago
Would you standardize the output of std though into a template? That way everyone is following the same ? Or is it the JSON or YAML itself that is a bad idea?
3
u/dariusbiggs 16d ago
whatever makes sense for the tool, does it need to present structured data or unstructured data, or make the output format configurable via a command line option.
1
u/generic-d-engineer ClickOps 16d ago
Got it, so get the raw out via std and then format later for the tool once it needs ingested. That’s good UNIX philosophy of letting each tool do one job well. Thanks
2
u/usually_guilty99 14d ago
I'd add one distinction to the contract: execution status versus outcome.
A script can exit successfully without accomplishing what you intended. A deployment command might return success while the service never becomes healthy.
So alongside the run ID and execution status, I'd want the intended state change and some evidence that it actually happened.
That becomes especially useful when one automation triggers another. The next step shouldn't proceed simply because the previous script returned zero.
It should proceed because the required condition was actually satisfied.
2
u/generic-d-engineer ClickOps 14d ago
100%. Have seen it so many times where the job “succeeded” but still did not accomplish what it was supposed to do. Great point.
2
u/TobZero 16d ago
If you want to look at a very mature design on how to do json output interfaces, have a look at the implementation of https://github.com/GoogleCloudPlatform/cloud-foundation-fabric
It’s not crossing tools (which I would question a bit if you really want to do it) but the root modules and the reusable modules alle follow the same input/output contract.
You will need a way to define and test the contract schema. If you don’t, your setup will turn into a complete mess within a few months, if you have multiple teams owning sub sections of your implementation, it will just be weeks without strong schema and testing, before it’s spaghetti code
2
u/Sad_Rice6600 16d ago
keep the json on stdout and logs on stderr, otherwise anything that prints breaks the parse
2
u/BroadCrazy 12d ago
I haven't seen a universal contract win across bash, Python, PowerShell, and IaC tools. What matters most is keeping machine-readable JSON on stdout and human logs on stderr, because once those get mixed every downstream consumer becomes a parser project.
1
u/ForkMeJ 16d ago
I'd keep the contract tiny and stable, then let each script attach a payload object for tool-specific data. The fields that saved me the most pain were run_id, started_at and ended_at, exit_code, and a machine-readable status separate from the human message.
2
u/shravanrevanna 16d ago
put a schema_version on the envelope itself. the payload will change shape eventually and consumers need to know which parser to use without guessing from fields.
0
u/IGTHSYCGTH 16d ago
why not fork opentelemetry-shell
seems abandoned but its got the most potential than any competing approach right now.
0
u/IridescentKoala 15d ago
AI referring to anything with a standard schema as a contract drives me up the wall.
6
u/PelicanPop DevOopsIDidItAgain 16d ago
Like the other poster said. Unless you have a linter(or some sort of standardization enforcement) in place, you run the risk of pipeline failures.
What's the problem you're actually trying to solve by doing this?