i've just started to work with prometheus-nginxlog-exporter
https://github.com/martin-helmich/prometheus-nginxlog-exporter
my nginx.conf has only one change
log_format custom '$remote_addr - $remote_user [$time_local] $request_method "$request_uri " $status';
access_log /var/log/nginx/access.log custom;
I have two simple site
server {
listen 82;
server_name localhost;
access_log /var/log/nginx/access_default_site.log custom;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
upstream prom {
server 127.0.0.1:9090;
keepalive 15;
}
server {
listen 80;
location / {
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/htpasswd.prom;
proxy_pass http://prom;
proxy_redirect off;
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header Connection "Keep-Alive";
proxy_set_header Proxy-Connection "Keep-Alive";
}
}
etc/prometheus-nginxlog-exporter.hcl
listen {
port = 4040
}
namespace "nginx" {
source = {
files = [
"/var/log/nginx/access.log"
]
}
metrics_override = { prefix = "allnginx" }
namespace_label = "vhost"
format = "$remote_addr - $remote_user [$time_local] $request_method \"$request_uri\" $status"
labels {
app = "prod"
}
}
namespace "default" {
source = {
files = [
"/var/log/nginx/access_default_site.log"
]
}
metrics_override = { prefix = "allnginx" }
namespace_label = "vhost"
format = "$remote_addr - $remote_user [$time_local] $request_method \"$request_uri\" $status"
labels {
app = "test"
}
}
if check prometheus metrics
curl http://localhost:4040/metrics
output is
# HELP allnginx_http_response_count_total Amount of processed HTTP requests
# TYPE allnginx_http_response_count_total counter
allnginx_http_response_count_total{app="prod",method="",status="200",vhost="nginx"} 28
allnginx_http_response_count_total{app="prod",method="",status="302",vhost="nginx"} 7
allnginx_http_response_count_total{app="prod",method="",status="400",vhost="nginx"} 30
# HELP allnginx_parse_errors_total Total number of log file lines that could not be parsed
# TYPE allnginx_parse_errors_total counter
allnginx_parse_errors_total{vhost="default"} 0
allnginx_parse_errors_total{vhost="nginx"} 0
allnginx_http_response_count_total{app="prod",method="",status="200",vhost="nginx"} 28
Why is method empty? How to configure it correct?
How to get statistics about requests to location e.g. how many requests to "/", "/api"
as mentions in documentations
https://github.com/martin-helmich/prometheus-nginxlog-exporter#custom-labels-pass-through
we should you relabel
my working config is
listen {
port = 4040
}
namespace "nginx" {
source = {
files = [
"/var/log/nginx/access.log"
]
}
metrics_override = { prefix = "allnginx" }
namespace_label = "vhost"
format = "$remote_addr - $remote_user [$time_local] $request_method \"$request_uri\" $status"
relabel "method" { from = "request_method" }
relabel "request_uri" { from = "request_uri" }
labels {
app = "prod"
}
}
namespace "default" {
source = {
files = [
"/var/log/nginx/access_default_site.log"
]
}
metrics_override = { prefix = "allnginx" }
namespace_label = "vhost"
format = "$remote_addr - $remote_user [$time_local] $request_method \"$request_uri\" $status"
relabel "method" { from = "request_method" }
relabel "request_uri" { from = "request_uri" }
labels {
app = "test"
}
}
in metrics we can see somthing like this
allnginx_http_response_count_total{app="prod", instance="localhost:4040", job="nginx", method="DELETE", request_uri="/api/dashboards/uid/GLEY_3g7k", status="200", vhost="nginx"}
1
allnginx_http_response_count_total{app="prod", instance="localhost:4040", job="nginx", method="GET", request_uri="/", status="302", vhost="nginx"}
1
allnginx_http_response_count_total{app="prod", instance="localhost:4040", job="nginx", method="GET", request_uri="/", status="401", vhost="nginx"}
2
allnginx_http_response_count_total{app="prod", instance="localhost:4040", job="nginx", method="GET", request_uri="/api/alerts/states-for-dashboard?dashboardId=2", status="200", vhost="nginx"}
1
allnginx_http_response_count_total{app="prod", instance="localhost:4040", job="nginx", method="GET", request_uri="/api/alerts/states-for-dashboard?dashboardId=3", status="200", vhost="nginx"}
I searched many forums , found many similar topics, but none works for me(
I have this configuration:
upstream 8083 { server 127.0.0.1:8083; }
upstream 8084 { server 127.0.0.1:8084; }
split_clients "upstream${remote_addr}" $default {
50% 8083;
50% 8084;
}
map $arg_upstream $upstream {
default $default;
"8083" "8083";
"8084" "8084";
}
location / {
if ($arg_upstream = "8083") {
proxy_pass http://8083;
break;
}
if ($arg_upstream = "8084") {
proxy_pass http://8084;
break;
}
proxy_pass http://$default;
}
But after going by url site/?upstream=8084 I have no switching to 8084 upstream.
If I test my config by changing to:
if ($arg_upstream = "8083") {
return 200 "upstream 8083"
}
if ($arg_upstream = "8084") {
return 200 "upstream 8084"
}
I see text perfectly like needed! Where am I going wrong?
Thanks!
this is answer to my question, it was decided by map 'http_cookies':
upstream default {
ip_hash;
server 127.0.0.1:8083;
server 127.0.0.1:8084;
}
upstream 8083 { server 127.0.0.1:8083; }
upstream 8084 { server 127.0.0.1:8084; }
map $arg_upstream $upstream {
'8083' '8083';
'8084' '8084';
default 'default';
}
map $http_cookie $upstream_cookie {
default '';
"~*upstream=(?<variable>[^;]+)" "$1";
}
and location part:
location / {
if ($upstream_cookie) { set $upstream $upstream_cookie; }
if ($arg_upstream) { add_header Set-Cookie upstream=$arg_upstream always; }
proxy_pass http://$upstream;
}
location ^~ /upload/images/ {
return 200;
}
location ^~ /admin/ {
return 300;
}
When I visit http://ip/admin/upload/images/pic.jpg , it return 300.
How could I do to make http://ip/admin/upload/images/pic.jpg and http://ip/upload/images/pic.jpg and http://ip/anyother/upload/images/pic.jpg return 200
I am new to nginx, and I need to return altered request and from my understanding it is made in body_filter_by_lua_block scope by setting ngx.arg[1]. This is a simple base example of my usecase:
server {
listen 80;
server_name localhost;
location / {
body_filter_by_lua_block {
ngx.arg[1] = '{ "Subject": "someval" }'
ngx.arg[2] = true
}
}
}
My question is, how can "someval" be turned into a variable, i.e:
server {
listen 80;
server_name localhost;
location / {
set $someval "hello";
body_filter_by_lua_block {
ngx.arg[1] = '{ "Subject": "$someval" }'
ngx.arg[2] = true
}
}
}
Your nginx variable is available for get and set in the lua block with ngx.var.someval.
I'm trying to setup varnish to handle my default url which is example.url.co.uk.
If it hits example.url.co.uk or example.url.co.uk/ I want it to redirect or rewrite to example.url.co.uk/site which within the tomcat application sends it to a login page.
sub vcl_recv {
if ((req.url ~ "") || (req.url ~"^/")) {
set req.http.location = "https://example.url.co.uk/site" + req.url;
return (synth(750, "Found"));
}
}
sub vcl_synth {
if (resp.status == 301) {
set resp.http.Location = req.http.x-redir;
return (deliver);
}
if (resp.status == 750) {
set resp.http.Location = req.http.location;
set resp.status = 302;
return (deliver);
}
}
However when I use my attempt that this I get example.url.co.uk/site/site/site/site...
So I'm obviously stuck in a loop and I've been banging my head on this for a week trying to find the right solution! Please save me from my own stupidity I'm sure!
the problem is that req.url ~ "" matches everthing. as it is used as a regular expression. also your req.url ~ "^/" is too open.
changing it to:
if (req.url == "" || req.url ~"^/$") {
should fix it, verifying that it is either empty or / it self.
here is a simple varnishtest to verify the behaviour:
varnishtest "Test Redirect"
server s1 {
rxreq
txresp
rxreq
txresp
} -start
varnish v1 -vcl+backend {
sub vcl_recv {
if (req.url == "" || req.url ~"^/$") {
set req.http.location = "https://example.url.co.uk/site" + req.url;
return (synth(750, "Found"));
}
}
sub vcl_synth {
if (resp.status == 301) {
set resp.http.Location = req.http.x-redir;
return (deliver);
}
if (resp.status == 750) {
set resp.http.Location = req.http.location;
set resp.status = 302;
return (deliver);
}
}
} -start
client c1 {
txreq -url "/"
rxresp
expect resp.status == 302
} -run
client c1 {
txreq -url "/site"
rxresp
expect resp.status == 200
} -run
you can run it with varnishtest test.vtc