0

I have lua block in nginx config, which checks for redis-server connection and if 4 java-processes are up, and then returns 200 or 500 status accordingly to this checks.

location = /healthcheck {

    content_by_lua_block {
        local redis = require "resty.redis"
        local red = redis:new()  
        red:set_timeout(1000)
        local ok, err = red:connect("127.0.0.1", 6379)
        if not ok then
            ngx.status = 500
            return
        end


        local ps = io.popen("/bin/ps aux |grep -c '[j]ava.*63'")
        local output = tostring(ps:read('*a'))
        ps:close()
        if string.match(output, '4') then
            ngx.status = 200
        else
            ngx.status = 500
        end
    }

}

But periodically output variable takes nil value, while it shouldn't. Just can't get why it happens.

Thanks in advance, comrades.

UPD:

Using tonumber fails on

bad argument #2 to 'tonumber' (number expected, got string)

Updated location config:

   location = /healthcheck {

        content_by_lua_block {
            local redis = require "resty.redis"
            local red = redis:new()
            red:set_timeout(1000)
            local ok, err = red:connect("127.0.0.1", 6379)
            if not ok then
                ngx.status = 500
                return
            end

            local ps = io.popen("/bin/ps aux |grep -c '[j]ava.*63'")
            local output = tonumber(ps:read())
            ps:close()
            if (output == 4) then
                ngx.status = 200
            else
                ngx.status = 500
            end
        }

    }

UPD2:

Logging to nginx error (with tostring) prints next:

grep: write error: Broken pipe
2016/04/19 17:54:48 [error] 301#0: *5 [lua] content_by_lua(healthcheck.conf:33):20: OUTPUT:nil

UPD3:

Using command grep -c '[j]ava.*63' <(/bin/ps aux) to avoid the use of pipe:

local ps = io.popen("grep -c '[j]ava.*63' <(/bin/ps aux)")

getting next error:

sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `grep -c '[j]ava.*63' <(/bin/ps aux)'
d.ansimov
  • 2,131
  • 2
  • 31
  • 54

1 Answers1

0

According to this answer and some testing next config do the job:

location = /healthcheck {

    content_by_lua_block {
        local redis = require "resty.redis"
        local red = redis:new()
        red:set_timeout(1000)
        local ok, err = red:connect("127.0.0.1", 6379)
        if not ok then
            ngx.status = 500
            return
        end

        local ps = io.popen("/bin/ps aux >/tmp/ps.out", "w")
        ps:close()
        local ps = io.popen("grep -c '[j]ava.*63' /tmp/ps.out")
        local output = tostring(ps:read())
        ps:close()
        if string.match(output, '4') then
            ngx.status = 200
        else
            ngx.status = 500
        end

    }

}
Community
  • 1
  • 1
d.ansimov
  • 2,131
  • 2
  • 31
  • 54
  • @Prashanth any proofs? It WORKED for me about 3 years ago. And, you know, the things, they're changing, so maybe it won't work for now. Maybe if you'd be more specific, someone would help you with your issue to make it work the way you want it to. – d.ansimov Apr 08 '19 at 06:14
  • Hi @cardinal-gray, I'm trying to get the output of my shell script but it doesn't give me any output or it doesn't even error. It runs fine when i run `curl -I http://localhost:9001``` but it's not creating that ps.out file on in temp directory. – Prashanth Apr 10 '19 at 18:14
  • error_log /var/log/nginx/error.log; events { worker_connections 1024; } http { server { listen 9001; location /tmp { default_type text/html; content_by_lua ' ngx.say("

    hello, world

    ") '; } location / { content_by_lua_block { local ps = io.popen("/bin/ps aux >/tmp/ps.out", "w") ps:close() local ps = io.popen("grep -c '[j]ava.*63' /tmp/ps.out") local output = tostring(ps:read()) ps:close() } } } } ```
    – Prashanth Apr 10 '19 at 18:15