msgbartop
by Brian Neal
msgbarbottom

24 Sep 09 I <3 Vim

I love the text editor Vim. I started using Vi because I really didn’t know any better around 1988 when I was first teaching myself C on my trusty Amiga 500. Not long after that I discovered Vim which sported many improvements over the venerable Vi. Sometime around 1993-1994 I started hacking Vim. I added a complete ARexx port to Vim so that you could script it. Alas, a new version of Vim came out right after I finished, and author Bram Moolenaar had changed the code so much I felt it was impossible to merge my changes into the new version. This was when I was a young pup programmer, and I was unfamiliar with revision control and difference/merging tools. I had fun doing it anyway, so I just chalked it up to experience.

I have used Vim on every programming task at every job I’ve had. I’m constantly learning new things about it, and the commands and keystrokes are now part of my DNA. I don’t even think how to execute commands anymore and I am often hard pressed to recall them to others learning Vim. I have to sit at a keyboard with Vim running in order to understand what my fingers are doing.

A while back, I discovered the auto-complete feature, where you type Ctrl-n in insert mode and Vim will attempt to complete the word you are typing based on all the words in all buffers and how frequently they occur. This is incredibly handy when programming to quickly pound out those function and variable names. I used “imap <S-Tab> <C-n>” in my .vimrc file to map this to shift-tab, which I felt was more convenient.

I also picked up a really handy way to cycle through all your buffers.  I used the tab and shift-tab mapping mentioned in that Vim tip. Combine that with Vim’s tab feature I can very easily find the file I am looking for.

And finally I had another big “wow, Vim can do that?” moment just last week. Since version 7, Vim has sported an “omni-complete” framework. Basically it is an architecture for people to hang code completion routines into Vim. In fact, right out of the box, Vim 7 has support for Javascript, CSS, and yes, even Python! Python completion is only available if you are using a version of Vim that has been compiled with Python support (e.g. on Ubuntu). Imagine my shock when I was editing a CSS file and I typed “display:” and then hit Ctrl-X Ctrl-O for the first time and a drop down list of all the possible values (inline, block, none, etc) appeared! No more hunting for that w3schools website. And the Python support is just as handy. Type “os.path.” followed by Ctrl-X Ctrl-O and you can see all the entities and function in the os.path module. I had no idea!

So all of this reminds me it is time to once again donate to the Vim project. Thanks Bram for all your amazing work you do on this invaluable tool.

P.S. I have no interest in the great editor holy war. Use a tool that you find intuitive and useful and learn it, back to front. I’m sure there is nothing wrong with other popular editors. But for me, Vim is it. I can’t imagine how many hours of productivity it has given me over the years.

Tags:

19 Sep 09 Server Monitoring with Munin

I finally got around to investigating server monitoring tools, and came across Munin. This tool allows you to monitor various nodes in your network, and it generates pretty graphs for a wide variety of system parameters. You install munin-node software on the machines you wish to monitor. The node software gathers statistics which are collected periodically by a munin master agent, which produces the nice graphs that you can view with a web browser.

Installing it was easy with Ubuntu, as packages already exist for it. It was a simple “sudo apt-get install munin munin-node.” The Ubuntu package set me up for running both the master and node software on the same machine. I then had to edit the /etc/munin/munin.conf to change a few paths around, notably where to put the generated HTML files. One hitch that stumped me for a few minutes was a permissions problem on the path to the location of the HTML files. The Ubuntu package creates a new munin user, so make sure all directories on the path to the HTML files have an “x” bit for world. Once that was sorted I started seeing data after 5 minutes for a variety of things including CPU load, MySQL statistics, and filesystem usage. Awesome! I decided to put Apache Basic Authorization password protection on the directory where the report files live, as it is sensitive data that I wouldn’t want just anyone to see.

Below is an example graph, one of about 50 (!) that are available right out of the box. Plugins exist and can be created for a wide variety of other parameters as well. In addition, Munin can notify you by email if parameters get out of range. See the Munin home page for more examples and information.

Munin MySQL Graph

Munin MySQL Graph

Munin looks like a very useful tool to keep an eye on your server. Thanks to the Munin team for this great piece of software!

Tags: , , ,

15 Sep 09 Django Tip: get_object_or_404() and select_related()

I was looking at the SQL my views were generating, and I came across a couple of places where I was using get_object_or_404(), and then later following some foreign keys in the returned object. Something like this:

forum = get_object_or_404(Forum, slug=slug)
if not forum.category.can_access(request.user):
     return HttpResponseForbidden()

The problem is that two SQL queries occur here, one during the get_object_or_404(), and then another in the following if statement, when we access category, a foreign key on the forum object. It would sure be nice to somehow use a select_related() there to avoid the extra SQL query. I did some googling, and found a quick tip on one of the This Week in Django podcast pages. And yes, the documentation confirmed that get_object_or_404() can now take as a first argument either a model, a manager, or a queryset!

So now you can keep using the handy get_object_or_404() idiom, and reduce the number of queries with a slight bit of refactoring:

forum = get_object_or_404(Forum.objects.select_related(), slug=slug)
if not forum.category.can_access(request.user):
     return HttpResponseForbidden()

Very cool!

Tags: ,

04 Sep 09 Denyhosts: SSH Brute Force Protection

I’m always very uneasy when I look through my web server and system logs. It seems dozens of people (or more!) a month try to log into my server, attempt an SQL injection attack on one or more of my hosted websites, and probe for weaknesses. It really makes me lose some faith in humanity.

I was tipped of to the Denyhosts script via a tweet from @dozba. This is nothing more than a Python script that analyzes your ssh log file, looking for suspicious activity. It monitors the number of failed SSH login attempts over time, and once a configurable threshold is reached, it adds the IP address of the remote host to your hosts.deny file, thus blocking the brute-force break-in attempt. The script is very configurable. It can have different thresholds for login attempts to existent or non-existent user accounts, it can purge blocked entries, and it will email you when it blocks a host.

Installation and configuration on Ubuntu is a breeze, as it is available as a package. Use your favorite package manager and install it. Ubuntu automatically configures it to run in daemon mode, so you won’t need to mess with cron. Configure it by editing the file /etc/denyhosts.conf. Restart the daemon, and then you are done. In a nutshell:

$ sudo apt-get install denyhosts
$ sudo vi /etc/denyhosts.conf
$ sudo /etc/init.d/denyhosts restart

Two days after I installed it, I had already blocked 5 break-in attempts. Thanks to the author Phil Schwartz and the Ubuntu package maintainers for this very useful utility!

Tags: , , ,