Log Serial Port Data to a Specified Logfile

By Bruce Garlock

I wrote this script to capture log data from our T1 routers for debugging purposes. There are some comments in the file for configuration. I run this in the background on Redhat 6.2 machines, at our remote locations. Eventually I plan to add more features, like logging to syslog, so I can get timestamps, which Multitech doesn't currently support on their routers. No warranty, and use at your own risk! (Seems to work fine in my environment, though) You could also port this to a win32 environment too.


#!/usr/bin/perl
#
#
# Author: Bruce S. Garlock
# Date:   2002-09-11
# Requirements: Device::SerialPort 0.12 (from cpan)
#
# Version: 0.1
#
#
# Description:  This perl script is for logging of data from a serial
# port, to a specified logfile.  The logfile can then be parsed with
# other programs for reporting purposes.
# 
# This program was written for specifically logging Multitech's
# MTASR2-203 T1 Router.  The router outputs text to the command
# port with 57.6k, 8-1-N, and No flow control.
#
#

use Device::SerialPort 0.12;

$LOGDIR    = "/var/log";              # path to data file
$LOGFILE   = "router.log";            # file name to output to
$PORT      = "/dev/ttyD015";          # port to watch

#
#
# Serial Settings
#
#

$ob = Device::SerialPort->new ($PORT) || die "Can't Open $PORT: $!";
$ob->baudrate(57600)   || die "failed setting baudrate";
$ob->parity("none")    || die "failed setting parity";
$ob->databits(8)       || die "failed setting databits";
$ob->handshake("none") || die "failed setting handshake";
$ob->write_settings    || die "no settings";

#
# Send a string to the port
#
#

$pass=$ob->write("AT");
sleep 1;

#
# open the logfile, and Port
#

open(LOG,">>${LOGDIR}/${LOGFILE}")
    ||die "can't open smdr file $LOGDIR/$LOGFILE for append: $SUB $!\n";

open(DEV, "<$PORT") 
    || die "Cannot open $PORT: $_";

select(LOG), $| = 1;      # set nonbufferd mode

#
# Loop forver, logging data to the log file
#

while($_ = <DEV>){        # print input device to file
    print LOG $_;
}

undef $ob;
 

See Device::SerialPort on Redhat 8 for updated information on this.


Got something to add? Send me email.





(OLDER) <- More Stuff -> (NEWER)    (NEWEST)   

Printer Friendly Version

-> -> Log Serial Port Data to a Specified Logfile


27 comments



Increase ad revenue 50-250% with Ezoic


More Articles by © Bruce Garlock







Fri Mar 4 21:58:02 2005: 107   anonymous


This is just what I need. What would make this better is if we could somehow pipe it to our ODBC database (running localy) so that we could keep track and massage the data easily. Not to mention be able to query it from applications in real time. If anyone has the slightest clue on how to do it, please send me in a direction.



Mon Mar 7 00:21:29 2005: 109   bruceg


This should not be too bad - you should be able to do it with the Perl DBI::ODBC module. I have had perl programs use ODBC databases before, even real old ones, so it should work for you. There are a lot of examples out there, just search google for perl odbc dbi example. Here is one basic one, that walks you through making DBI::ODBC, and a simple example script:
(link)

I am sure there are plenty more out there, just search google. Here is a larger example, providing all sorts of SQL commands with Perl:
(link)

--BruceGarlock



Mon Mar 7 00:26:01 2005: 110   bruceg


Here is a link to the Perl ODBC HOWTO - this is what should really help you out:

(link)

--BruceGarlock



Tue Aug 23 23:59:14 2005: 1015   james


love the script. I also want to upload the items inot a mysql db but that will come later. My problem is that whenever i run the script "perl logger.pl" it runs but if there is no out put from the printer interfaces it ends. From what i understand it should keep going adding a new line when req. What am i missing??



Wed Aug 24 14:05:05 2005: 1020   bruceg2004


hmmmm - What exactly are you using the script for? You mention printer, so I am not 100 sure what you are trying to accomplish. I simply use the script to take data from a router that has a serial console connection, and sends it's data to that serial connection, so I wrote this to take that data, and log it to a file using Linux/Perl.

Let me know your intent, and application, and I will see what I can do to help you.

- Bruce






Wed Aug 24 22:34:46 2005: 1022   james


Thanks for raqpid reply. My application. I have a control panel that has a 232 printer port. obviously this is designed fopr attaching a printer but i wanted to do more with it. Basicaaly as anything happens on the panel it prints the event out. (40 column i think) I would ideally like to capture this date to MySql new line new record etc. Capturing time of event (from local machine) a string of text used to identify the bit of kit on the port and the text itself

Basically thats it. I plan to use multiple machines onto 1 database eventually as i need to monitor a fair bit of kit.

Hope that answers your questions

cheers James



Fri Aug 26 18:43:50 2005: 1033   bruceg2004


OK, I see. You know for a fact that the panel is printing messages, and for some reason, the above perl script is not logging anything to a file? Keep things simple at first, make sure we are getting data from the port, and able to log it to a ascii file, before we through an db into the mix.

Also, no Perl errors, correct? If you keep things simple, I think the script should work fine, if your rs232 port is working fine. What are the settings of the port? Baud rate, flow control, etc.. It is possible you may need to change those settings in the perl script. Also, what kind of cable are you using? If you are getting zero data, try swapping the RX, TX pins - I have had to do this for some serial printers, so it may be possible, that your printer has things reversed?

Also, is this a "standard" serial port on a PC, or part of a multiple serial port card like a DigiBoard, or Stallion Board?

- Bruce






Fri Aug 26 21:14:13 2005: 1034   TonyLawrence

gravatar
I *think* he's saying that he gets data but then the script ends, which means it read an eof. So he just needs to wrap the DEV loop in an outer while (1) loop.






Sun Sep 11 21:47:00 2005: 1072   anonymous


Yes it does work but after about 10 seconds of no output it stops when run from console.



Sun Sep 11 21:48:55 2005: 1073   anonymous


Sorry Ill add a bit more info. Yes i know the panel is printing as it works briefly.
I changed the setting of the script to match my printer module eg 9600 no parity

And yes its ttyS0

James



Sun Sep 11 22:53:05 2005: 1074   TonyLawrence

gravatar
As I said above, you need to wrap your DEV loop in an outer while (1) block. Your device is returning eof but you want to keep reading..



Mon Sep 12 00:03:34 2005: 1075   anonymous


i assume an eof is end of file. But the unit i am using is expecting to be plugged into a serial printer. It cant send this eof, or can it? Im just checking we are on the same wavelength. Thanks for repid replies!!

James



Mon Sep 12 07:33:37 2005: 1077   TonyLawrence

gravatar
Whether you think it should or not, it is apparently closing and resetting the connection. Put the loop around it and be done with it.



Wed Oct 12 10:52:53 2005: 1187   anonymous


Tony could you please write out what you mean by outer (1) loop? I'm new to programming in pearl.






Wed Oct 12 10:59:59 2005: 1188   TonyLawrence

gravatar
It's Perl, not Pearl, and you must be new to programming of any kind :-)

The "outer loop" would be a loop enclosing another loop. In this case,
the modified code would look like this

#outer loop
while (1) {
# inner loop
while($_ = <DEV>){ # print input device to file
print LOG $_;
}
# end inner loop
}
# end outer loop



Thu Oct 13 14:06:54 2005: 1195   bruceg2004


OK, trivia time! What is it called when you have yet another loop imbedded inside the inner loop?



Fri Oct 14 14:33:32 2005: 1201   bruceg2004


I should have mentioned, this is *not* a rhetorical question - I was wondering what the proper term is, since I just call them "nested". Is that correct?







Fri Oct 14 14:41:56 2005: 1202   TonyLawrence

gravatar
I'd call them nested, yes.



Thu Sep 28 16:18:16 2006: 2488   anonymous


How would you manipulate this script to talk to com port 2 in a Win XP environment?
Thx



Thu Sep 28 16:38:57 2006: 2489   anonymous


I am not sure how to do this on WinXP. I am not even sure how Perl handles COM ports in XP, as I only use Windows if I have to. I do all my programming in the Unix world (mostly Linux), so I would see how other people have implemented Device::SerialPort in Windows, to see how this is done.

I think most of the people who visit this site are primarily Linux and other *nix users, so searching Google Groups or the web should turn up something. I do know that Perl will run in Windows, it's just that I have never done it. Have a look at this link:
(link)

In the See Also section, it mentions Win32API::CommPort -- which may be what you need in addition to Device::SerialPort. Windows certainly handles devices much different than *nix, where every device is a filename in the *nix world. Actually, that paradigm is one of the main reasons that I checked out Linux, and kept using it. It makes programming much easier (I think).

Best of luck, and don't feel threatened by giving linux a whirl. Also, what are you using this for?

Best Regards,

Bruce



Thu Sep 28 17:33:49 2006: 2490   anonymous


I'm writing some scripts to automate testing of an external device running an embedded OS. I need to caputre codes from the debug port of the device and parse for pertanent information. I'm new to Perl too but looks like it won't be too difficult.

Thanks for the suggestions.



Thu Feb 4 22:03:08 2010: 8030   anonymous

gravatar


Thanks for the perl script! It has proven to be very useful in watching FireAlarm panel's printer output. I cant say exactly what brand or anything, but this script is working swimmingly on an Ubuntu Netbook, using a USB-Serial adapter no less. Very practical and to the point. Is there any potential addition to the script that could give a local terminal echo in addition to logging the incoming ASCII. I am not a bigtime perl guru, and am just curious mostly, I currently just fork the script off of the terminal (making note of the pid) and then tail -f the logfile, I was just wondering if there was a better way to have my cake and eat it too, both log, and view. Thanks!



Fri Feb 5 03:26:12 2010: 8031   TonyLawrence

gravatar


You could write to a specific console tty - I have systems set up like that so you can just do ALT-F4 or whatever to see a particular log output.



Tue Feb 9 21:10:25 2010: 8049   RussH

gravatar


If you are using this to monitor a serial port which has gaps in the data stream (i.e. isn't sending data all the time) then you need to amend the last while loop otherwise the script will exit as soon as the first gap is detected. Revised loop reads as as follows;

while(1) {
($iCount, $sStr) = $ob->read(1);
if ($iCount >= 1) {
print LOG $sStr;
}
}

A far brainier colleague than I figured this out for me - thanks Dale!



Sat Oct 23 12:27:23 2010: 9054   TonyLawrence

gravatar


While looking for a way to get serial data to my iPad, I came across
(link)

They make a pricey but interesting RS232 to Wireless dongle:
(link)



Wed Mar 27 22:12:31 2013: 11996   Mike

gravatar


@james: did you find a solution to store the captured serial Data in a MySQL DB? I have exactly the same requirement.
Tks!



Fri Mar 29 20:18:06 2013: 11999   TonyLawrence

gravatar


I don't know if you'll get an answer from James, but Perl has modules for MySQL (although really MySQL is so trivial you could do it with "system").

------------------------
Kerio Samepage


Have you tried Searching this site?

Unix/Linux/Mac OS X support by phone, email or on-site: Support Rates

This is a Unix/Linux resource website. It contains technical articles about Unix, Linux and general computing related subjects, opinion, news, help files, how-to's, tutorials and more.

Contact us