Is there a way to truncate a field's contents that is stored in the access log?

I am interested in keeping only the first ten characters of User-Agent.


First, you introduce a custom variable that contains the truncated user agent. For that you use the map directive on the regular user agent variable, $http_user_agent. The documentation for the map module is here: http://nginx.org/en/docs/http/ngx_http_map_module.html. Then you configure the logging format using the log_format directive, see the documentation at https://docs.nginx.com/nginx/admin-guide/monitoring/logging/. Finally, you tell the access_log to use your custom logging format.

In summary:

# ...
http {
    map $http_user_agent $trunc_agent {
        default "";
        "~*(?P<tr>.{0,10}).*" $tr;
    log_format myformat '[other fields] "$trunc_agent"';
    access_log [logfile] myformat;
# ...
| improve this answer | |
  • Thanks, but the document is silent on where to add the map directive. I tried to put it in /etc/nginx.conf and it says "map" directive is not allowed here. – Old Geezer Aug 28 '18 at 7:29
  • That's strange -- I have just verified that the map instructions provided by ngx_http_map_module are included "out of the box" and no additional module configurations are loaded via include (on my machines). So putting them in /etc/nginx.conf SHOULD work. A search in this forum reveals that it should be enabled and installed by default: serverfault.com/questions/780778/… Do you have any custom compiled version? Or a hosting solution that disables some modules? – user8472 Aug 28 '18 at 11:06
  • Oh, I got it to work by putting map as a block nested in http. (Earlier I was putting it on the same level as http.) But it always give me the value I have in default. I configured the log to show both the truncated version and the standard $http_user_agent and I can confirm that even if there is a user agent, the result of map is that default value. The documentation doesn't say much about the syntax for the map directive. Thanks. – Old Geezer Aug 28 '18 at 13:38
  • Sorry, I should have provided a little more context. I had included all expressions at the same level (and that was meant to be inside the http section). I have clarified it in the edit. Furthermore, the regular expression was buggy -- I missed the .* at the end! I have now verified that the current form does what you asked for! – user8472 Aug 28 '18 at 14:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.