I am testing nginx and want to output variables to the log files. How can I do that and which log file will it go (access or error).
6 Answers
You can send nginx variable values via headers. Handy for development.
add_header X-uri "$uri";
and you'll see in your browser's response headers:
X-uri:/index.php
I sometimes do this during local development.
It's also handy for telling you if a subsection is getting executed or not. Just sprinkle it inside your clauses to see if they're getting used.
location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt)$ { add_header X-debug-message "A static file was served" always; ... } location ~ \.php$ { add_header X-debug-message "A php file was used" always; ... }
So visiting a url like http://www.example.com/index.php will trigger the latter header while visiting http://www.example.com/img/my-ducky.png will trigger the former header.
- 38Note that
add_header
will work on successful requests only. Documentation states that it can only be applied to responses with codes 200, 204, 301, 302 or 304. Therefore, it can't be used to debug HTTP errors.John WH Smith– John WH Smith2014-08-25 14:43:46 +00:00Commented Aug 25, 2014 at 14:43 - 44@JohnWHSmith : As marat noted in this answer. As of version 1.7.5, nginx added an "always" parameter to
add_header
which will return the header, no matter what the response code. So for example,add_header X-debug-message "A php file was used" always;
, should work even for 500 error code.yuvilio– yuvilio2015-09-22 20:24:19 +00:00Commented Sep 22, 2015 at 20:24 - 21This doesn't answer the question at all. The guy wants to log to log file not to the client.Avamander– Avamander2018-04-17 11:31:28 +00:00Commented Apr 17, 2018 at 11:31
- Doesn't work. I am doing proxy_pass. The header is NOT present in the response.Arrow_Raider– Arrow_Raider2021-03-29 16:07:53 +00:00Commented Mar 29, 2021 at 16:07
- answering @Avamander you are right! OP asked a simple question how to render custom logging... can be done using Nginx directive: set $append_log 'custom_field=$custom_data';bellasys– bellasys2023-09-19 15:12:52 +00:00Commented Sep 19, 2023 at 15:12
You can return a simple string as HTTP response:
location / { add_header Content-Type text/plain; return 200 $document_root; }
Or use interpolation for watching multiple variables at the same time:
location / { add_header Content-Type text/plain; return 200 "document_root: $document_root, request_uri: $request_uri"; }
- 2What if you want to return two variables values?BringBackCommodore64– BringBackCommodore642018-03-16 16:41:44 +00:00Commented Mar 16, 2018 at 16:41
- Going to the location immediately opens the Save As dialog of my browser (tested on Opera, Chromium). No response whatsoever.BringBackCommodore64– BringBackCommodore642018-03-16 17:27:18 +00:00Commented Mar 16, 2018 at 17:27
- @BringBackCommodore64 Adding a text/html Content-Type header may help.CuriousGeorge– CuriousGeorge2019-05-09 20:26:37 +00:00Commented May 9, 2019 at 20:26
-
- 2I want to return multiple variables and solved it like this;
return 200 "xforwardedfor:$proxy_add_x_forwarded_for--remote_addr:$remote_addr--scheme:$scheme--host:$host";
kursat sonmez– kursat sonmez2020-11-27 13:15:13 +00:00Commented Nov 27, 2020 at 13:15
You can set a custom access log format using the log_format
directive which logs the variables you're interested in.
- 2thanks, and I guess there is no easier way to output one variable by itself?lulalala– lulalala2012-07-04 05:39:48 +00:00Commented Jul 4, 2012 at 5:39
- @lulalala Not that I know of.mgorven– mgorven2012-07-04 05:42:16 +00:00Commented Jul 4, 2012 at 5:42
- It is possible set the log level in the directive
error_log
todebug
so you can see the value of the variables and that block that are execute. Exampleerror_log file.log debug
Victor Aguilar– Victor Aguilar2017-01-10 00:55:48 +00:00Commented Jan 10, 2017 at 0:55 - 2notice thar empty variables are shown as
-
in the log, but are really empty in the nginx code, you should not check for-
at any time. This sometimes confuse users.higuita– higuita2017-05-05 12:56:02 +00:00Commented May 5, 2017 at 12:56
Another option is to include the echo module when you build nginx, or install OpenResty which is nginx bundled with a bunch of extensions (like echo.)
Then you can simply sprinkle your configuration with statements like:
echo "args: $args"
- 2When I try this it echos out to a plain text file on the server interrupting the output of the actual page.JaredMcAteer– JaredMcAteer2015-05-07 17:36:23 +00:00Commented May 7, 2015 at 17:36
- 1There is an
echo_log
directive in development.Gajus– Gajus2017-07-14 16:16:47 +00:00Commented Jul 14, 2017 at 16:16 - 2@Gajus Three years later now, and I googled for this, but can't find anything about
echo_log
. Do you know if it ever got out of development?Randall– Randall2020-10-30 18:14:23 +00:00Commented Oct 30, 2020 at 18:14
none of these answer the question as asked (log)
However, @Victor Aguilar - has a comment on this answer, that should be an answer! It says how to log variables, and it works. Thanks!
https://serverfault.com/a/404628/400075
i.e. in /etc/nginx/nginx.conf
error_log /var/log/nginx/error.log debug;
results in the following type of logging:
2021/03/06 15:14:48 [debug] 2550#2550: *1 fastcgi param: "SCRIPT_FILENAME: /usr/lib/cgit/cgit.cgi/something.git/cgit.cgi" 2021/03/06 15:14:48 [debug] 2550#2550: *1 http script copy: "QUERY_STRING" 2021/03/06 15:14:48 [debug] 2550#2550: *1 fastcgi param: "QUERY_STRING: " 2021/03/06 15:14:48 [debug] 2550#2550: *1 http script copy: "REQUEST_METHOD" 2021/03/06 15:14:48 [debug] 2550#2550: *1 http script var: "GET" 2021/03/06 15:14:48 [debug] 2550#2550: *1 fastcgi param: "REQUEST_METHOD: GET" 2021/03/06 15:14:48 [debug] 2550#2550: *1 http script copy: "CONTENT_TYPE" 2021/03/06 15:14:48 [debug] 2550#2550: *1 fastcgi param: "CONTENT_TYPE: " 2021/03/06 15:14:48 [debug] 2550#2550: *1 http script copy: "CONTENT_LENGTH" 2021/03/06 15:14:48 [debug] 2550#2550: *1 fastcgi param: "CONTENT_LENGTH: " 2021/03/06 15:14:48 [debug] 2550#2550: *1 http script copy: "SCRIPT_NAME" 2021/03/06 15:14:48 [debug] 2550#2550: *1 http script var: "/cgit/cgit.cgi/something.git/cgit.cgi" 2021/03/06 15:14:48 [debug] 2550#2550: *1 fastcgi param: "SCRIPT_NAME: /cgit/cgit.cgi/something.git/cgit. cgi" 2021/03/06 15:14:48 [debug] 2550#2550: *1 http script copy: "REQUEST_URI" 2021/03/06 15:14:48 [debug] 2550#2550: *1 http script var: "/cgit/cgit.cgi/something.git/" 2021/03/06 15:14:48 [debug] 2550#2550: *1 fastcgi param: "REQUEST_URI: /cgit/cgit.cgi/something.git/" 2021/03/06 15:14:48 [debug] 2550#2550: *1 http script copy: "DOCUMENT_URI" 2021/03/06 15:14:48 [debug] 2550#2550: *1 http script var: "/cgit/cgit.cgi/something.git/" 2021/03/06 15:14:48 [debug] 2550#2550: *1 fastcgi param: "DOCUMENT_URI: /cgit/cgit.cgi/something.git/" 2021/03/06 15:14:48 [debug] 2550#2550: *1 http script copy: "DOCUMENT_ROOT" 2021/03/06 15:14:48 [debug] 2550#2550: *1 http script var: "/usr/lib" 2021/03/06 15:14:48 [debug] 2550#2550: *1 fastcgi param: "DOCUMENT_ROOT: /usr/lib" 2021/03/06 15:14:48 [debug] 2550#2550: *1 http script copy: "SERVER_PROTOCOL" 2021/03/06 15:14:48 [debug] 2550#2550: *....
- 3not all nginx packages ar buit with --with-debug flag so debug directive is useless in error_log if nginx built with --with-debug (as I see most of nginxes are built without)Ivan Borshchov– Ivan Borshchov2021-05-27 11:02:21 +00:00Commented May 27, 2021 at 11:02
The 1st question: how to log a variable?
You can set error_log to debug, and then use if with a regexp that matches everything, eg ^
. This method works like a built-in echo.
You can even "name" your log just like ^|some_name
.
For example:
server { error_log /dev/stderr debug; if ( $variable1 ~ "^|varlable1" ) { set $a ''; } location { if ( $variable2 ~ "^|var2" ) { set $a ''; } if ( $variable3 ~ "^|var3" ) { set $a ''; } } }
Note: just like lots of other things in nginx,
if
can be used only inserver {}
orlocation {}
example output:
"^|var3" matches "https://example.com" while ...
The 2nd question: Which file it will go to?
error_log <the_file_you_want_it_to_go_to> debug;