One of the first things that I reach for when writing an application that will be used outside the context of my development sandbox is a configuration library. Not having statically compiled values for variables is quite a valuable position to be in once your application has been deployed. Today’s post will take you from 0 to up and running with a package called ConfigFile that is specifically designed to serve your applications with configuration data. Most of the content in this post is lifted directly from the documentation, so you’ll be better off reading through those to gain a deeper understanding of the library. This post is more of a short-cut to get up and running.
Configuration format
If you’ve had much experience with administering windows back in the day when INI files ruled the earth, you’ll be right at home with ConfigFile. For those of you who have never seen it before, it’s really easy and you can read up on it here. Files are broken into sections which contain a list of key/value pairs - done!
For today’s example, the configuration file will look as follows:
[Location]path=/tmpfilename=blah
We’ll end up with two keys, path and filename that have corresponding values in the Location section.
Structure
The thing I like most about the part of the application is that we can make a nice record based data structure in Haskell that will marry up to how our configuration file looks. The simple file that we’ve defined above, would look like this:
Once we fill one of these up, you can see that it’ll be pretty natural to access these details.
Reading and Building
Finally - we need to read the values out of the config file and get them into our structure. The following block of code will do that for us.
readConfig::String->IOConfigInforeadConfigf=dorv<-runErrorT$do-- open the configuration filecp<-join$liftIO$readfileemptyCPfletx=cp-- read out the attributespv<-getx"Location""path"fv<-getx"Location""filename"-- build the config valuereturn(ConfigInfo{path=pv,fileName=fv})-- in the instance that configuration reading failed we'll-- fail the application here, otherwise send out the config-- value that we've builteither(\x->error(sndx))(\x->returnx)rv
There’s a few interesting points in here to note. The Error Monad is being used here to keep track of any failures during the config read process. runErrorT kicks this off for us. We then use readfile to open the config file with a sane parser that knows how to speak INI. Pulling the actual strings from the config is done by using get. From here, it’s just wrapping the values up ready to send out. The final call is to either. Leaving the Error Monad, we’re given an Either (left being the error, right being the value). I’ve used either here so I can provide an implementation for either scenario. If an error occurs (the first lambda) then I just toast-out of the application. If we get a config value back (the second lambda), that’s what gets returned.
Conclusion
That’s all there is to that. Remember, you won’t escape from the IO Monad which is why the read function’s return type has IO. When you want to use these values, it’ll need to be within do constructs:
main::IO()main=doconfig<-readConfig"test.cfg"putStrLn$"The path value is: "++(pathconfig)putStrLn$"The filename value is: "++(fileNameconfig)
Working in a Linux environment for more and more of the day, it pays to know your tools really well. One tool that I use frequently to understand what a machine is doing is the top command. Today’s post will take you through all of the figures on this report to help you understand what each means.
The Command
The top command is a very common tool used to “display Linux tasks” as the man page so helpfully tells us. Issuing this command at the shell will present the user with a few rows of figures followed by a list of all running processes on the system. Here is an extract of the report (just the upper lines that this post will focus on).
Breaking Down the Summary
You can see from the excerpt above that quite a lot of information is packed into this part of the report. To breakdown this report, I’ll just got through it line by line.
top - 20:52:24 up 24 min, 2 users, load average: 0.93, 1.01, 0.93
The first line tells us the following:
The current time (20:52:24)
The machine’s up time (24 min)
How many user sessions currently (2)
The system’s load average for the last minute (0.93), last 5 minutes (1.01) and last 15 minutes (0.93)
The system load average is an interesting one. A general rule of thumb is to investigate if you’re seeing averages above 0.7. An average of 1.0 suggests that just enough work is getting processed by the machine, but is leaving you no headroom to move. Seeing a load of 5 and above is panic-time, systems stalling, trouble. For more information about these load values, take a look at Understanding Linux CPU Load - when should you be worried?
The third line gives you a point in time view of how busy the CPU is and where its cycles are being used. It tells us the percentage of CPU being used for:
User applications (12.3 us)
System applications (4.9 sy)
Applications that have had their “nice” value adjusted (0.0 ni)
The fourth and fifth lines deal with memory and swap utilisation. It tells us the following:
Total
Used
Free
Buffers
Cached
That’s it for the summary of the machine’s activity. These are all the aggregate values which will give you an “at a glance” feel for how the machine is going. The next part of this post will be all about reading specific information from the process report. Here’s an excerpt of the report.
Breaking Down the Process Report
To interrogate a single process, you can use the details within the process report. It will list out all of the processes currently managed by your system. The report columns as you look at it will provide the following information:
The process ID (PID)
The user who owns the process (USER)
The priority (PR)
The nice value (NI)
Virtual memory used by the process (VIRT)
Physical memory used by the process (RES)
Shared memory for the process (SHR)
Status of the process (S) (Sleeping, Running, Zombie)
Percentage of CPU used by this process (%CPU)
Percentage of memory used by this process (%MEM)
The time that this process has been active (TIME+)
The name of the process (COMMAND)
That’s it for the “top” command in Linux. Remember, always read the man pages for commands that you want to learn more about!
Getting a wider array of fonts into your website is a pretty simple task these days. There’s quite a selection of fonts that you can use offered on the web. Just take a look at Google’s repository to see what I’m talking about.
Once you’ve selected the font that’s right for your application, you can import it to pages using the following directive:
A quick reminder post to myself to go and look at Flat Assembler. Interest was sparked initially from a article that was more of an x86 assembly tutorial here
Testing is a large component of any software development done, sometimes though - you don’t want to go through a full unit test suite just to see what a REST service is doing. I’ve come across some interesting concepts with cURL that will certainly be a shortcut benefit to seeing what responses your REST services are returning.
Requests
You can simulate all of the different HTTP verbs against any URL you’d like using cURL with the following syntax at the console:
# Retrieve person (id: 1)$ curl -i-X GET http://localhost/service/people/1
# Retrieve all people$ curl -i-X GET http://localhost/service/people
# Delete person (id: 1)$ curl -i-X DELETE http://localhost/service/people/1
# Create a new person$ curl -i-X POST -H'Content-Type: application/json'-d'{"first_name": "John", "last_name": "Smith"}' http://localhost/service/people
# Modify a person (id: 1)$ curl -i-X PUT -H'Content-Type: application/json'-d'{"first_name": "Jane", "last_name": "Smith"}' http://localhost/service/people/1