Showing posts with label logstash. Show all posts
Showing posts with label logstash. Show all posts

Monday, June 1, 2015

GridFTP Log Analysis with Logstash and Kibana / Elastic Search

As noted in my post about Lustre Stats with Graphite and Logstash we are huge fans of the ELK (Elastic Search, Logstash, Kibana) stack.  In that last example we didn't use the full ELK stack but in this example we are going to use ELK what it was meant for, log parsing and dash-boarding.

We run a GridFTP server using the Globus.org packages. GridFTP for those who don't know is a better performing way to transfer data around. If you want to setup GridFTP please use the globus.org Globus Connect Server, its much easier than setting up the certificate system, and it quickly becoming the standard auth and identity provider for national research systems.

GridFTP logs each transfer with your server.  What I want to know his where, who, and how much is going though the server.  I have been running this setup for a while now, but it could use some refining.  You can find my full logstash config as of this writing at Gist.

First the results:


Logstash has a number of filters that makes this easier.  We use the regular Grok filter to match the transfer stats lines from the GridFTP log.  You could modify this to capture the entire log in Elastic search for archive reasons.  Then the kv (key value) filter does a wonder on all of the log files key=value entries doing most of our work for us.

I have to use a few grok filters to get the IP of the remote server isolated, but once done logstash has a built in geoip filter that tags all the transfers with geolocation information which lets the maps be created.  Oh and in the dashboard those maps are interactive, so you can sort transfers just from another country by clicking on that country, or adding a direct filter for the country code, zipcode, etc.  Really handy.

Individual transfers are also mapped by what campus they are coming from if coming from a University address.  Our sub nets across the three campuses are known and published, so we use the cidr filter to add a tag for each campus, so we can look at traffic from a specific campus.  Again really handy, and would love to get contributions to see what traffic comes from internet2 / MiLR and the commodity internet.

A few warnings, the bandwidth calculation is commented out for a reason.  It works, but not all GridFTP log entries are complete to do the calculation, this makes ruby get angry and makes logstash hang.

So it was very easy to use logstash to understand the GridFTP log files, then the rest of the ELK stack let us quickly make dashboards for our file transfers. 

I was inspired to write this after thinking there must be an easier way to handle GridFTP logs after a presentation at XSEDE 14 where the classic, scripts, plus copy log files, system was employed.  The solution here is near real-time, and we found to be very durable.

Friday, October 31, 2014

Lustre Stats with Graphite and Logstash

A while back Matthew Britt who handles most of our HPC Scheduler and Resource Manager services got fed up with the problem of debugging the distributed nature of jobs. We had logs on 1000+ nodes, server, scheduler, and accounting manager. To solve this he build a solution around the ELK stack, Elasticsearch, Logstash, and Kibana. His solution was one of the most useful user support and job debugging tools ever.  You can see Matt's talk form MoabCon on YouTube.

Once Matt showed me how easy this is, I instantly got an idea, Lustre, it's another distributed problem. In this case I didn't care about logs I cared about time series data, and I had two goals to solve.
  1. What is our filesystem performance over time, in both bandwidth and open/close opps.
  2. Find the users who open 999999 files/s in a single code.
To handle time series data rather than Elasticsearch I used Graphite a tool that has been around awhile. Think of it as RRD, but with a data collector for creating databases on the fly over the network, and with great performance.

All the config files used at the time of writing this are available on Github.

First some pictures:


So how did I easily get these data? Enter Logstash and the exec {} input. Because lustre stores all its summary stats in directories like /proc/fs/lustre/[mdt|obdfilter]/stats and /proc/fs/lustre/[mdt|obdfilter]//exports//stats I had to make my own handler.  Why couldn't I just cat the stats files? Logstash being designed for log files, sees each line as an event and parses them each on their own.  In our case I want the entire file.  The solution to this was to make a simple python script that turns the stats into json objects.

json-stats.wrapper.py

./json-stats-wrapper.py /proc/fs/lustre/mdt/scratch-MDT0000/md_stats  | python -mjson.tool
{
    "close": "241694077",
    "crossdir_rename": "300771",
    "getattr": "439797690",
    "getxattr": "3393359",
    "link": "117530",
    "mkdir": "1332774",
    "mknod": "1209",
    "open": "789470206",
    "rename": "522526",
    "rmdir": "1289414",
    "samedir_rename": "221755",
    "setattr": "12991707",
    "setxattr": "118798",
    "snapshot_time": "1414810134.237384",
    "source": "/proc/fs/lustre/mdt/scratch-MDT0000/md_stats",
    "statfs": "799026",
    "sync": "43951",
    "unlink": "25767242"
}
Logstash if told that the input data is json, will now treat this as an event. In general the logstash-lustre.conf and logstash-lustre-mds.conf configs parse each event, including the path to the stats and grabs each counter and builds a metric form it.

One wants to be smart about your groupings. Lucky for us the Lustre devs did things in a very logical way, and it almost falls in our laps.  You will use these groups/wildcards with graphite to quickly make lots of plots for the same metric over all OST's, MDT's, or clients, etc.
lustre....
Eg: lustre.scratch.MDT.0000.open
Eg:lustre.scratch.OST.*.10-255-1-100.read_bytes

I don't calculate any rates in logstash.  I chose to store the raw counter value from the stats files.  Graphite has built in lots of nice functions that let you calculate your rates like nonNegativeDerivative() which deals with counters that roll over such as reboot.  So keep your data quite raw.

Be careful with the number of metrics and your Graphite storage schema.  We keep our per OST/MDT data for a year (10s:7d,10m:30d,60m:180d,6h:1y) and per client stats for 30 days (2m:30d).  In our case we have over 1000 clients, 30 OSTs 1 MDT and we store 16 metrics/MDT, 16 metrics/MDT/client, 18 metrics/OST, 4 metrics/OST/client.  In call we store 53,300 metrics just for lustre. This is about 14GB of data right now, and because of the way Graphite works will not grow unless we add more metrics, or add more clients.

The more likely problem is you send metrics to fast for graphite, and the number of IO's your graphite server disk can provide won't be up to task. In our case we update OST/MDT summary stats every 10 seconds, and client OST/MDT stats every 2 minutes.  This is being handled with single 7,200 RPM SATA drive with some tweaking.

Future work:
  • Use logstash to alert us for slow_attr and LBUG events.
  • Use the DDN SFA SNMP MIB to get raw SFA counters into Graphite
  • Alert if an OST is set deactivate or in recovery/out of recovery.