-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deprecate and remove common_log field from access logs and single_field encoder #4148
Comments
I agree with this change, but it will be a breaking change for some people who rely on it to feed into tools like fail2ban and such, which don't support structured logs yet. I think before we remove it from Caddy, we should have a clear and easy way to maintain this behaviour. Maybe this means adding a preset to the Also, We'll also need to add a Edit: Actually the format-encoder module as-is would actually break when given the defaults (i.e. |
The field `{common_log}` is being deprecated along with all of its reference (see: caddyserver/caddy#4148). This commit is the first step in rebuilding the CLF template to avoid breaking users of this module for the sake of reconstructing CLF.
* internalize the CLF template The field `{common_log}` is being deprecated along with all of its reference (see: caddyserver/caddy#4148). This commit is the first step in rebuilding the CLF template to avoid breaking users of this module for the sake of reconstructing CLF. * use remote_addr, which includes the port, in place of the remote host BREAKING: users of CLF will start seeing the port along with the remote host
This will likely happen in v2.5.0 #4282 |
Closes #4396, related to #4148 This is a breaking change, but we're already planning on removing the`common_log` field as well at the same time, so might as well all do it together. In general, the remote IP is the useful part of the remote address. The port is rarely useful, because it only identifies ephemeral information about the connection from the client. But we were logging both in one field, so certain tooling that would want to only get the remote IP would need to split it up. Splitting is non-trivial, because of IPv4, IPv6, shenanigans. So it's best if we split it up-front before logging. If the log consumer actually cares about the remote port, it can re-assemble it.
Closes #4396, related to #4148 This is a breaking change, but we're already planning on removing the`common_log` field as well at the same time, so might as well all do it together. In general, the remote IP is the useful part of the remote address. The port is rarely useful, because it only identifies ephemeral information about the connection from the client. But we were logging both in one field, so certain tooling that would want to only get the remote IP would need to split it up. Splitting is non-trivial, because of IPv4, IPv6, shenanigans. So it's best if we split it up-front before logging. If the log consumer actually cares about the remote port, it can re-assemble it.
Closes #4396, related to #4148 This is a breaking change, but we're already planning on removing the`common_log` field as well at the same time, so might as well all do it together. In general, the remote IP is the useful part of the remote address. The port is rarely useful, because it only identifies ephemeral information about the connection from the client. But we were logging both in one field, so certain tooling that would want to only get the remote IP would need to split it up. Splitting is non-trivial, because of IPv4, IPv6, shenanigans. So it's best if we split it up-front before logging. If the log consumer actually cares about the remote port, it can re-assemble it.
This is now done and merged, and will land in v2.5.0 |
Is the intended way to interface fail2ban with Caddy 2.5+ really to compile it yourself with the transform plugin added? Or is there a different method to accomplish what fail2ban does with "vanilla" Caddy? I feel like rate limiting, blocking based on 4xx / 5xx responses, etc. are important parts of running a web server, and it feels like implementing this got harder with 2.5+, but maybe I'm looking at it all wrong. |
Rather, our opinion is that fail2ban should modernize, and support structured logging. Common Log is legacy. Also, it's trivial to build Caddy with plugins. We make it very easy to do so. You just need to install Go (which just means to download and unzip it, and add it to your PATH), then download and run Or, you can download a build produced by our build server at https://caddyserver.com/download. Or if you're using Docker, use the For rate limiting, you could also use this plugin: https://github.com/mholt/caddy-ratelimit |
We had to decide long ago that Caddy couldn't be in the business of integrating with every program, service, provider, and protocol out-of-the-box. Sorry if that is inconvenient, but we make it as easy as possible to customize your builds. Otherwise you'd end up with a 500MB binary that is a nightmare to configure, maintain, and ironically, build (dependency hell). And actually, ideally all that functionality you describe would just be provided by caddy directly, without needing external dependencies and C code. caddy has plugins for what you say you need, and it also has plugins to integrate with the tools you want. So, just take your pick, I guess. |
Frankly, I don't think there is a Caddy plugin to write I also didn't really like the decision to remove the (old-fashioned or not) still most commonly used log format "over night" with a minor version update. My fail2ban and a couple of other tools have stopped working, too. Some I fixed, for some I just accepted it. I didn't repair fail2ban, yet, but I'd assume you could probably quite easily write your filter regex for structured logging. For JSON logging it might be a bit harder. If you find something, or come up with your own filter, I think a lot of people will appreciate it, @AD-Wright! |
First, it was not "overnight", we warned that we would do this many months before doing it. Also, Caddy doesn't strictly follow semver. We have no plans for a Caddy v3 currently. Think of v2 as the product name, and "2.5" as the major version. Second, it was entirely redundant data, and can be reproduced from the structured logs. For users that didn't need it, it was a waste of space in their logs. For those users, it can be considered a "bug" to be logging those redundant bytes. Again, there's a totally sufficient workaround that exists by using the https://github.com/caddyserver/transform-encoder plugin which even has a Common Log preset to make it as easy as possible. Just use that. |
That sounds like a great candidate for a Caddy plugin! I'm not really familiar with iptables (I've used it once or twice) so someone with chops should write it. To be clear, CLF support has always been a misfeature, only implemented to enable a smoother transition from v1 to v2. Ever since the launch of v2 we've been recommending the transition to modern tools and formats that support more efficient and useful structured logs. |
True, but that's also why many programs meant to interface with a web server use it (and not the modern, structured logging). It's also a little puzzling from the user side that it even existed in v1 to begin with then! (But that's how it goes sometimes)
I had no idea about https://caddyserver.com/download! One of my concerns was in actually compiling with xcaddy on the VPS it's running on - Caddy runs great on little-to no hardware, but compiling not so much. Being able to download a pre-compiled binary is great. Also, something I struggled with (and figured out just now) is the necessity of compiling a "plugin" into the main program. I have zero familiarity with Go, but to me something that has to be compiled into a program is a "patch", not a "plugin". "Plugin" evokes just copying a file somewhere, à la Minecraft. It seems like terminology is migrating towards package or module, which I think makes more sense. However, in going down this route a bit further, I noticed that Caddy also has the
Fair point. This seems like a very small addition, but I get that in order to have a really small base package the "fat-trimmers" have to be a little aggressive. Looking at some other threads and @muety 's experience, it seems like perhaps the deprecation of CLF preceded the availability of some tools that really made the workaround... work. If plugins are intended to be as easy as Finally, congrats on 100 releases! This project has really accomplished a lot. |
Thanks! The community has been awesome to get us to this point. And thanks for understanding :) |
The Commons Log format was dropped in caddy 2.5, cf. [1]. [1]: caddyserver/caddy#4148
When Caddy 2 was being designed a couple years ago, there was still a lot of dependence on common-log-based workflows. Common Log Format (CLF) is bad, because it contains fields which are almost never used in modern HTTP, and it omits obvious fields like Host. This necessitates outdated workflows that separate each log emission into a separate file based on Host. And if you want to organize your logs by more than Host, or something other than Host, it gets even more complicated. And this does not scale well on the modern web, where most servers handle multiple domains -- some Caddy instances serve tens of thousands of hosts. CLF is too rigid to be useful in advanced deployments. It is also inefficient to generate CLF in Caddy's otherwise-zero-allocation logs, and impossible to filter them at emission-time because they're unstructured.
We make the case for structured logging in our official documentation.
Caddy 2 uses JSON logs. To support CLF in Caddy 2, we construct the CLF line and add it to the JSON message emitted for each HTTP request as a separate field. This has the unfortunate side-effect of bloating each and every access log message, and also makes them harder to read/scan. It contains only duplicate information that has to be extracted to be parsed as a subtext anyway.
A log encoder module,
single_field
, was created as a hack to be able to write purely CLF-formatted log files without any JSON. This was a short-term solution, not a well-engineered one.Nowadays, modules like the transform encoder exist which can emit access logs in a custom format. They're not zero-allocation of course, but you can do what you want: including CLF if you really need it still.
The common log format is a thorn in the side of Caddy's logs, and I intend to:
common_log
field from access logs.single_field
log encoder.single_field common_log
example from the docs: https://caddyserver.com/docs/caddyfile/directives/log#examplesI already have considerable weight behind this motion, but in true OSS fashion I wanted to make my intentions clear and open it to discussion before finalizing these changes shortly after the v2.4 release.
The text was updated successfully, but these errors were encountered: