Logfile monitor

Onelog is a program to watch your log files and display them in a condensed and colorful way.

Each line's time is shaded by how old the line is. New lines are pink (like the current time at the bottom), but they turn to gray over about an hour. The background of the server name is determined by the name itself; the foreground depends on the type of activity (incoming mail, http error, etc). Selected hostnames may have colors assigned to them. Finally, any substring in the rest of the line can cause the line to be colored.

Hostnames should be stored as IP addresses in the log files. Onelog's filters include a caching DNS lookup to resolve names. You can edit the cache to give hosts logical names. In the screenshot, "Dot" is my machine.

There's no friendly install, and the code may contain details particular to my setup, but you're welcome to have it. The code is in Tcl/tk and perl. Untar this in a new directory where you have made links to the log files you want onelog to watch. (It searches for files with these names: messages, syslog, Z2.log, access_log, error_log.)

onelog.tgz (first release, 12/14/2000)

It uses these perl modules:

Time::HiRes
File::Tail
Date::Manip

My Berkeley apartment


California king size bed from Diamond Mattress!

I'm building a big desk with shelves for all my parts. The right side and back walls have 14 levels of shelves already and lots more are planned.

8/27/2002 - I've moved out of this apartment and taken the desk to a house. There are a few more shelves on it now.

Zaurus - dimmer

Here, I used the Zaurus to wirelessly dim the desk lamp. The PyQT program is below.

When I adjust a slider, the program sends messages over XMLRPC to a server on one of my desktop boxes. That box sends the levels to my K8000 IO card, which you can see in the background of the image. That card sends 0-10V control signals to 4 dimmers around the room.

#!/usr/bin/env python
from __future__ import division
import sys,xmlrpclib,socket
from qt import *
Vertical = 1

class Dimmer(QVBoxLayout):
    maxval = 300
    def __init__(self,parent,name,serv):
        QVBoxLayout.__init__(self)

        self.serv,self.name = serv,name

        lab = QLabel(name,parent)
        lab.setFont(QFont("Sans", 10))
        self.addWidget(lab)

        sli = QSlider(0,self.maxval,self.maxval//10,self.maxval,
                      Vertical,parent)
        self.addWidget(sli)

        self.connect(sli, SIGNAL('valueChanged(int)'), self.changed)

    def changed(self,val):
        val = 1-val/self.maxval
        self.serv.setLight(self.name,val)

class Dimmers(QWidget):
    def __init__(self, *args):
        QWidget.__init__(self, *args)

        self.serv = xmlrpclib.ServerProxy("http://dot.bigasterisk.com:%s" %
                                          socket.getservbyname("lights","tcp"))

        self.setCaption("Light dimmers")
        cols = QGridLayout(self, 2, 5)

        for pos,name in enumerate(self.serv.listLights()):
            dim = Dimmer(self, name, self.serv)
            cols.addLayout(dim, pos//5, pos%5)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.connect(app, SIGNAL('lastWindowClosed()'), app,
                  SLOT('quit()'))
    d = Dimmers()
    d.show()
    app.setMainWidget(d)
    app.exec_loop()

Zaurus - hotplug

I tried for a few minutes to put the commands here into a file in /etc/hotplug/usb/usbnet, but things weren't working right. CDCEther kept coming up, and even reading the CDCEther source file didn't tell me what CDCEther was. I had installed hotplug from scratch, and I couldn't tell what it was doing or where it made its decisions.

As I want something quite simple-- run some shell cmds when I plug a device into usb, run some other ones when I disconnect it-- I hacked the top of /etc/hotplug/usb.agent to run my own hotplug system. Here's how to change the top of /etc/hotplug/usb.agent so it runs your own program, and then abort if your program is successful (otherwise, we proceed with the normal usb.agent):

...
cd /etc/hotplug
. hotplug.functions
# DEBUG=yes export DEBUG


###############################################################################
###############################################################################

/etc/hotplug/drewp-plug
if [ $? = 0 ]; then
  exit 0
fi
mesg "proceed with old usb.agent"

###############################################################################
###############################################################################

# generated by modutils, for current 2.4.x (and later) kernels
MAP_CURRENT=$MODULE_DIR/modules.usbmap
...

Then, I quickly wrote my own hotplug program:

#!/usr/local/bin/python
import os,sys,logging

# SysLogHandler isn't working, so i log to stdout and
# send that to syslog.
sys.stdout=os.popen("/usr/bin/logger -t drewp-plug","w")
log=logging.getLogger()
hdlr = logging.StreamHandler(sys.stdout)#SysLogHandler()
hdlr.setFormatter(logging.Formatter("%(levelname)s (%(lineno)d): %(message)s"))
log.addHandler(hdlr) 
log.setLevel(logging.INFO)

def run(cmd):
    log.debug("running %r" % cmd)
    os.system(cmd)

def zaurus_add():
  for l in """modprobe usbnet
      ifconfig usb0 192.168.129.1 netmask 255.255.255.255 up
      dhcpd -q usb0
      route add -host 192.168.129.201 usb0
      iptables -t nat -F
      iptables -t nat -A POSTROUTING -j SNAT -o eth0 --to 10.1.0.229
      echo 1 > /proc/sys/net/ipv4/ip_forward""".splitlines():
    run(l.strip())

def zaurus_remove():
    run("kill `cat /var/run/dhcpd.pid`")



##############################################################################
try:
    product={'4dd/8004/0':'zaurus',
             '4a9/3065/1':'digicam',}[os.getenv("PRODUCT")]
except KeyError:
    log.warn("product %s unknown to /etc/hotplug/drewp-plug" % os.getenv('PRODUCT'))
    sys.exit(1)

func=locals()["%s_%s"%(product,os.getenv("ACTION"))]
logging.info("calling %r" % func)
func()

sys.exit(0)

Among the unfortunate hacks in this program are:

  • spawning /usr/bin/logger because of some issue with SysLogHandler
  • hardcoding the product ID codes in here, instead of using whatever table hotplug was using (I don't even know where that is)
  • writing the program in the first place instead of u sing the standard hotplug system completely

But the benefits are:

  • it's not in written in shell
  • my Zaurus is hotplugging sooner than it would have, and I won't have to adjust this for a long time

Zaurus - networked

How I got the Zaurus networked for the first time

I mostly followed this page to get going. My Z is an SL-5500 with ROM ver 2.38, so it seems that the notes about the closed ports apply to me.

Z sits in the usb cradle, and its network setup has 'USB - TCP/IP' with automatic address (dhcp). Here are the commands that I run (2.4.22 kernel) to get networked:

modprobe usbnet
ifconfig usb0 192.168.129.1 netmask 255.255.255.255 up
dhcpd -q usb0
route add -host 192.168.129.201 usb0
iptables -t nat -F
iptables -t nat -A POSTROUTING -j SNAT -o eth0 --to 10.1.0.229
echo 1 > /proc/sys/net/ipv4/ip_forward

Where 10.1.0.229 is my machine's address on my local net. My /etc/dhcpd.conf looks like this:

# empty subnet for eth0, where i don't want dhcp
subnet 10.1.0.0 netmask 255.255.0.0 {
}

subnet 192.168.129.0 netmask 255.255.255.0 {
  option routers 192.168.129.1;
  option domain-name-servers 10.1.0.1;
  range 192.168.129.201 192.168.129.204;
}

where 10.1.0.1 is my name server.

Once I was networked, I surfed to http://www.myzaurus.com/downloads.asp on the Z and had Opera download the terminal .ipk package into /home/root/Documents where it can be installed with the 'add software' program.

To ssh to the zaurus, get openssh. Move the new files from /usr/local/bin/ to /usr/bin so they get found in the basic path. (scp/rsync will depend on that). On the Z, run ssh-keygen -b 1024 -f /usr/local/etc/ssh_host_key -N '' (see here for more, but note the typo on /usr/local/etc). Then add ssh stream tcp nowait root /usr/sbin/tcpd /usr/local/bin/sshd -i to /etc/inetd.conf and run /etc/rc.d/init.d/inet restart.

I also added these lines to inetd.conf to block qpe's ftp and other sync services:

4242 stream tcp nowait root /bin/false false
4243 stream tcp nowait root /bin/false false
To make those take effect, kill the qpe process then quickly HUP the inetd process so it grabs the ports first. Use "netstat -pl" to see what process is listening on what port.

To ssh to root@zaurus from my non-root user, I added this section to my desktop's .ssh/config:

Host z
 User root

scp and rsync had trouble connecting to the Z because their Z-installed versions were in /usr/local/bin.

Zaurus - radio

I got the "Sound feeder FM Stereo Transmitter" "SF 121" for $20 at Fry's. This means the Z has an attachment that's a bit smaller than a miniDV tape, and it broadcasts its audio on an adjustable FM station.

I have sshd and rsync on my z now, so I can easily rsync files to a 256MB CF card. The first mp3 files I sent wouldn't play with the standard player program, so I tried making constant bit rate files with "lame -b 80 infile.mp3 outfile.mp3". These files are smaller due to the low bitrate, and they play fine.

In the San Francisco bay area, the radio spectrum is very busy, so it's hard to find a quiet spot to broadcast from the little transmitter. I'm on 87.7FM for now, but on the high bridges (where I presume the real 87.7 signal is least obstructed), I can barely hear my own signal. Everywhere else, there's a little white noise but it's quite tolerable. I am considering compressing my audio waveform as I down-convert it so I can push through the noise just a little bit more. On the freeway, though, I rarely notice the noise.

Zaurus - schedule view

I want a constant view of the current and upcoming datebook items on my secondary computer screen (which normally just scrolls web and system logs).

Presuming I rsync my /home/root to my big computer's disk frequently/automatically, I can read datebook.xml and draw what's inside. Here's the hack to do that (for python 2.3 with gnosis xml).

Today is green, older is purple, future is gray. The program actually writes my schedule text. I did the streaking on this image.

Zaurus - wlan

The Zaurus has a Linksys WCF11 CF card, and the desktop has a D-Link DWL-122 (usb) interface.

I was able to install the prism2_usb driver from here, but wasn't able to get it to be the host AP for other devices to find.

A DI-524 wireless router works, though. I disabled its DHCP and set my wireless devices (including zaurus) to fixed addresses.

Microphone power supply

I've got a lavalier microphone that needs external power which I want to use with my video camera. The goal is to accept balanced XLR in, and output unbalanced both-channels-the-same stereo audio. Also, if the mini plug to the camera is unplugged, the closure of the switch inside the jack should turn the power supply off.


Here's my lousy plan. 9V battery puts 9V on each of the +sig and -sig incoming signal lines. A transformer makes a new signal out of the difference between +sig and -sig (which should be twice the signal, with noise cancelled out).

The transformer specs are inset at the bottom-right. I have probably really screwed up the impedances for the mic (200 ohms) and the camera (don't know). Please send suggestions if you know better.


The parts, laid in the final case.


A prototype version of the project.


The finished circuit board and connected components.


Back of the case, showing the belt clip.


Front of the case, showing the output jack.