I needed a simple system to monitor events. I wanted to have a system where
I can specify that object with some name is 'ok' or 'fail'. And I wanted the
system to be able to expire statuses. In case there is no data for the
object for a long time then the status should be automaticly changed to
'unknown' — to handle situations when script that sends data breaks.
I looked for several systems, but none suited me well, so I've written
my own very simple solution with the name 'curry' (it is named after
delicious indian dish, not after Haskell Curry =)
Here is the source code — https://github.com/bessarabov/curry
The system is a web server that is powered by Dancer
and the system is bundled into an image with Docker.
I really like this way of creating web apps with Dancer & Docker. Every time
there is a new commit in git report Docker Hub automatically builds new
image.
Here is the power of Docker, to run curry you need to install
Docker and when you have docker
installed you need to enter just one (!!!) command to have curry up and
running:
docker run --publish 15000:3000 bessarabov/curry:1.0.0
This command downloads image from Docker Hub and runs it. This will create
web server on port 15000 on your Docker (in case of linux the Docker usually
works on 127.0.0.1, is case of mac you can find our Docker ip with the command
boot2docker ip
and in case of windows read the docs).
This way of running is super simple and it works pretty well to play a bit
with this project, but in production you should do several more things.
First of all you need to create persistent storage for curry. Curry stores
all its data in sqlite database stored in file. To make persistend storage
you should store that file outside the docker container (more details in the
docs).
The other thing that you may like to do in prodoction environment is to add
authorization
and to run it on https.
So, we have curry up and running, I would like to show several real life
examples.
Setting the object with the name 'zero_inbox' to 'ok':
curl -H "X-Requested-With: XMLHttpRequest" "http://curry:15000/api/1/set?path=zero_inbox&status=ok&expire=1d"
You can see that we also specified "expire=1d". You must specify this
parameter with your first request. The "X-Requested-With" header is used to
prevent CSRF attacks.
Let's set one more object:
curl -H "X-Requested-With: XMLHttpRequest" "http://curry:15000/api/1/set?path=jenkins&status=fail&expire=1d"
So now we have information about statuses of two object. Curry has several
endpoints that allows get information about current situation.
With endpoint "get" you can get info about all objects with problems:
curl -H "X-Requested-With: XMLHttpRequest" "http://curry:15000/api/1/get"
It will return:
{
"success" : true,
"result" : {
"status" : "fail",
"objects" : [
{
"path" : "jenkins",
"status" : "fail"
}
]
}
}
True value for "success" tells us that endpoint worked fine and gave us
answer that we can see in "result" value. "result.status" is "fail" that
means that we have some objects with statues "fail" or "unknown". In the
"result.objects" we have an array with the broken objects.
There is also an endpoint "get_all". It has the exact answer structure, but
gives information about all objects:
curl -H "X-Requested-With: XMLHttpRequest" "http://curry:15000/api/1/get_all"
{
"success" : true,
"result" : {
"status" : "fail",
"objects" : [
{
"path" : "jenkins",
"status" : "fail"
},
{
"path" : "zero_inbox",
"status" : "ok"
}
]
}
}
Lets set that jenkins is fixed (as you can see for the second request we can
not specify "expire"):
curl -H "X-Requested-With: XMLHttpRequest" "http://curry:15000/api/1/set?path=jenkins&status=ok"
Now we have two objects in curry and all of them have "ok" status. We can
check that with "get" endpoint:
curl -H "X-Requested-With: XMLHttpRequest" "http://curry:15000/api/1/get"
{
"success" : true,
"result" : {
"status" : "ok",
"objects" : []
}
}
There is one more endpoint in curry that allow inspecting the current
situation. It is endpoint "get_object" that returns all known info about
the object:
curl -H "X-Requested-With: XMLHttpRequest" "http://curry:15000/api/1/get_object?path=jenkins"
{
"success" : true,
"result" : {
"path" : "jenkins",
"status" : "ok",
"expire" : "1d",
"history" : [
{
"status" : "fail",
"dt" : "2015-02-09 14:23:23"
},
{
"dt" : "2015-02-09 14:33:41",
"status" : "ok"
}
]
}
}
So this is all that curry can do. It is just a simple storage of the objects
statuses. There is no webinterface — one can use JSON endpoint and add it to
existing dashboards.
So, here is my tiny project and I would be extremely happy to hear from you
what do you think. Please you the comments, or write GitHub
Issue or
email me.