Why stdout for logs in Factor12?
Asked Answered
E

2

9

I have recently discovered https://12factor.net/ — a set of requirements for production environment that look quite sensible, except for logging requirements.

https://12factor.net/logs says that logs should go to STDOUT. WAT? WHY?

I've been mostly managing for last 7 years and must have missed something. But I do clearly remember that STDERR was design to serve this exact purpose — be a separate stream for diagnostic information. And it's been used as such for decades.

Why breaking the convention?

I do remember that all HTTP servers by default were configured to send STDOUT to a browser (client) and send STDERR to log files. It was everywhere. It's obvious and default for most of environments. My first thought is that they authors of the 12-factor standard have made a mistake.

What am I missing? Why sending logs to STDOUT?

Please don't tell me that modern web-applications don't have "normal output". Firstly they do, secondly, this doesn't qualify as a justification to break the convention that worked for decades and is still perfectly fit for purpose.

I'd appreciate your thoughts. Thank you.

Elmer answered 26/8, 2017 at 11:42 Comment(0)
A
4

Keep in mind that the 12factor applies mainly to your applications or let's call it your "micro services", not to your servers like Nginx, Apache, Cherokee, etc that they can log as always, but your application is the one you may want to scale and will be deployed in distributed environments, therefore, needs to be handled differently.

Regarding the logging, the main idea is to avoid the application write to disk and just write to STDOUT or STDERR, normally the logs are in a "structured logging" format, and later collected/analyzed by tools like elastiksearch. These simplify the process of checking logs so that if something is wrong, you don't need to login to each server and check what is happening.

In many cases when applications write log to disk, if a log rotate mechanism is not properly configured, the server disk may become full and service will be interrupted.

In case you are looking for a supervisor that plays well with 12factor.

Twelve-factor app processes should never daemonize or write PID files. Instead, rely on the operating system’s process manager (such as Upstart, a distributed process manager on a cloud platform, or a tool like Foreman in development) to manage output streams, respond to crashed processes, and handle user-initiated restarts and shutdowns.

Check immortal it can either combine STDOUT and STDERR or log separately besides also letting the log intact without timestamp in the case is a structured log that later may be used by elastic search, or any other tool, example:

cmd: microservice
env:
  DEBUG: 1
  ENVIRONMENT: production
log:
  file: /var/log/app-1.log
  age: 86400 # seconds
  num: 7     # int
  size: 1    # MegaBytes
  timestamp: true # will add timesamp to log

Same service but with STDOUT and STDERR logs separated:

cmd: microservice
env:
  DEBUG: 1
  ENVIRONMENT: production
log:
  file: /var/log/app-1.log
  age: 86400 # seconds
  num: 7     # int
  size: 1    # MegaBytes
stderr:
  file: /var/log/app-error.log
  age: 86400 # seconds
  num: 7     # int
  size: 1    # MegaBytes
  timestamp: true # will add timesamp to log

More about the run.yml can be found here: https://immortal.run/post/run.yml/

Adolphadolphe answered 7/9, 2017 at 19:52 Comment(2)
Thanks, nbari, for the advertisement. You still did not answer the question. It doesn't matter which server I am using (if any) to receive requests. The same log aggregation can done with both STDOUT and STDERR. Why breaking the convention of using STDERR for logging?Elmer
Indeed normally STDOUT & STDERR are combined but in a "structured logging" format, normally JSON so that the single output file can be later parsed, analyzed etc by tools like elastiksearch, is an approach that helps maintain and scale applications easierAdolphadolphe
M
0

It's because 12-factor apps are expected to run as separate processes under the control of some process manager - like supervisord or something - to manage routing application outputs to where they actually belong.

Their idea is to make the apps as agnostic as possible - handling all outputs of all apps in a system-dependent manner, while hiding all of that from the app.

So, I expect the "12-factor" response would be that your app should push to STDOUT, and supervisord should capture that output (along with all the other STDOUTs from all your other apps running on the same host) and redirect to STDERR or syslog or whatever you need, on a per-host basis.

Update

I thought 12-factor recommended daemonized processes, but because reasons (pids and all that) they actually don't. Further evidence that the process manager portion of 12-factor is critical.

Martinez answered 28/8, 2017 at 20:47 Comment(3)
you did not answer the question why stdout, as stderr still can be captured and redirected to wherever required. Moreover, if you say "make the apps as agnostic as possible" they must then feed their logs to stderr and their output to stdout because it was the original design. If you don't know your environment, then you just follow the standard. It's the safest way.Elmer
Yeah, I guess I don't really know the answer - hopefully Wiggins has explained it somewhere... I can say that Heroku captures both STDOUT and STDERR from apps, letting you manage them both independently; because both STDOUT and STDERR would be lost/inaccessible otherwise (i.e. in a fully "cloud" environment where you can't access the server).Martinez
Yesterday I have emailed Adam Wiggins with a request to explain it with a link to this page.Elmer

© 2022 - 2024 — McMap. All rights reserved.