WebAssembly / wasi-logging

WASI logging API
19 stars 5 forks source link

Should wasi-logging have a "critical" or "fatal" log level? #9

Closed sunfishcode closed 1 year ago

sunfishcode commented 1 year ago

The README file has an explanation of why there is no "critical" or "fatal" log level. In short, the answer is that programs should just use the "error" level and follow it with a trap or an exit if that's what's desired.

However, as noted in the README, log4j, Ruby's, Python, and .NET all do have a "critical" level, so it's worth considering the alternative.

Is there a use case for marking log levels as critical, where it's desirable to do something different than a regular error plus a trap or exit?

PiotrSikora commented 1 year ago

The README file has an explanation of why there is no "critical" or "fatal" log level. In short, the answer is that programs should just use the "error" level and follow it with a trap or an exit if that's what's desired.

The README says that there is no critical log level, but it doesn't really explain why.

However, as noted in the README, log4j, Ruby's, Python, and .NET all do have a "critical" level, so it's worth considering the alternative.

Is there a use case for marking log levels as critical, where it's desirable to do something different than a regular error plus a trap or exit?

All those languages didn't add it by accident, so clearly there is a need for a fatal log level. All the log level in current version are non-fatal. I think the primary use case is log filtering, e.g. so that you could alert users/operators that they need to check the system as soon as possible.

Another is the interaction between Wasm VMs and host, e.g. we use critical level to log panic! messages in Proxy-Wasm Rust SDK.

But even without a clear use case, one simple argument for keeping critical log level is that programs already written in those languages that are using critical log level could be compiled against wasm32-wasi target without a need to adjust the log levels.

IMHO, the latter alone is good enough justification, especially in the absence of a good reason for removing it.

sunfishcode commented 1 year ago

I've been thinking about this from the opposite direction: If we have a Critical level and environments use that level to alert users/operators, then programs written in languages where Error is the highest level would have no way to alert users/operators, short of modifying them to call WASI-specific APIs. Consequently, I've been imagining that "alert people" would happen as the result of a trap, or as the result of Errors from specific components, and not as the result of a log itself, so an Error level would be the highest level needed.

Another consideration is modular vs. monolithic applications. In modular applications, the effective severity of a problem is often determined by the program as a whole, which individual components aren't aware of. For example, a markdown renderer doesn't know if it's handling sensitive user data or frivolous memes. If the renderer hits a fatal problem from its perspective, it should report the problem, but it doesn't know what the failure means to the rest of the system. Also, in modular applications in systems with many fine-grained log levels, it can be difficult to ensure a consistent interpretation of the levels (eg. when should one use "info" vs. "notice", or "error" vs. "critical" vs. "alert" vs. "emergency"), across independently-developed components. So if we're designing an API for monolithic applications, it might make more sense to lean into finer-grained log levels. But if we're designing an API for modular applications, it might make more sense to lean more into the context argument and the linking configuration to determine effective severity levels.

PiotrSikora commented 1 year ago

But critical error doesn't mean that you need to trap the program, I think that's a wrong assumption and those things don't need to be related. One example is a disk I/O error (e.g. full disk) that you should log as critical and alert the user, without trapping, because like you've said, individual components don't know how they affect the whole system, and in that case failing a single operation instead of bringing the whole system down might be a better choice. Similarly, if your application fetches/receives dynamic config updates and one update is corrupted, then it probably makes sense to log critical error and continue operating with the old config instead of exiting the application.

Also, modular vs. monolithic is not a new concept, there is a ton of applications that use 3rd-party libraries, and it somehow works in the real world, so I don't understand why we want to make things different in WASI.

sunfishcode commented 1 year ago

After thinking about this more and talking to others, I've changed my mind here. @PiotrSikora Would you mind rebasing #10 to fix the merge conflict? Since there haven't been any other objections here, I think we can go ahead and merge that.

PiotrSikora commented 1 year ago

@sunfishcode I updated that PR last week, in case you've missed it.