Plugin Output is Unparsable — Logging in a Protobuf Plugin
Logging to stdout is not possible when using protoc. To avoid that, write to stderr or use a framework that does it for you or logs to a file instead.
protoc-gen-*: Plugin output is unparseable: ...
, did you ever receive this error-message? Logging is an essential tool for most software developers to understand failures and find bugs. Yet, protoc can make this complicated and the above error-message is often the result. Here’s how you can log anyways. The code is available on GitHub.
What’s the problem?
Protoc uses stdin
and stdout
to communicate with its plugins. If a logger writes to stdout
, protoc
tries to parse that output. Since the log-statement is meant to be read by humans, this parsing will fail. Therefore, a protoc plugin cannot use stdout
for anything else but communicating code generation results back to protoc
.
What can be done?
1. Just print to stderr
A straight-forward solution is to just print to stderr instead of stdout. In the example of python, you can do that, by specifying a file in a print-statement:
print("Generating protobuf...", file=sys.stderr)
If you make that change, protoc will succeed:
This approach works and may be the simplest one, if you just need things to work quickly. For a more permanent solution, I recommend using a proper logging framework.
2. What’s better? — Use a logging framework
Logging frameworks offer more flexibility like logging to files, different log-levels or printing the file name and line where the log occurs. In fact, the Python logging facility, by default, writes its output to stderr
. To use it, first configure the logger. To be on the save side, you can specifically set the stream to stderr. Then log something:
import logging
logger = logging.getLogger(__name__)
logging.basicConfig(
stream=sys.stderr,
level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s"
)
if __name__ == "__main__":
logger.info("Generating protobuf...")
...
The result is a working compilation with a good amount of extra helpful information and the flexibility to redirect logs to a file for later analysis.
Conclusion
Logging to stdout is not possible when using protoc. To avoid that, write to stderr or use a framework that does it for you or logs to a file instead.
Do you want to know more about writing protoc plugins? Check out my series on that topic.