I have been reading about how to keep error/warning logs of a C program on Linux environment. Is it better to write the errno to a file as it is done here or is it better to use syslog or setlogmask system calls or another method? I would appreciate an answer with an example code.
I would strongly suggest using syslog for logging errors as its more standard way of logging.
you can look at the example implemenation here (bio3d.colorado.edu/tor/sadocs/misc/syslog.html)
Also unix network programming book by richard stevens also contains good explanation of using syslog
The above link no longer works - try this one here:
https://www.gnu.org/software/libc/manual/html_node/Syslog-Example.html#Syslog-Example
....which contains the following example:
#include <syslog.h>
setlogmask (LOG_UPTO (LOG_NOTICE));
openlog ("exampleprog", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
syslog (LOG_NOTICE, "Program started by User %d", getuid ());
syslog (LOG_INFO, "A tree falls in a forest");
closelog ();
Related
I've got several USB to 422 adapters in my test system. I've used FTProg to give each adapter a specific name: Sensor1, Sensor2, etc. They will all be plugged in at power on. I don't want to hard code each adapter to a specific ttyUSBx. I want the drivers to figure out which tty it needs to use. I'm developing in C for a linux system. My first thought was to something like this in my startup code.
system("dmesg | find_usb.py");
The python script would find the devices since each one has a unique Product Description. Then using the usb tree to associate each device with its ttyUSBx. The script would then create /tmp/USBDevs which would just be a simple device:tty pairing that would be easy for the C code to search.
I've been told...DoN't UsE sYsTeM...use posix_spawn(). But I'm having problems getting the output of dmesg piped to my python script. This isn't working
char *my_args[] = {"dmesg", "|", "find_usb.py", NULL};
pid_t pid;
int status;
status = posix_spawn(&pid, "/bin/dmesg", NULL, NULL, my_args, NULL);
if(status == 0){
if(waitpid(pid, &status, 0) != -1);{
printf("posix_spawn exited: %i", status);
}
I've been trying to figure out how to do this with posix_spawn_file_actions(), but I'm not allowed to hit the peak of the 'Ballmer Curve' at work.
Thanks in advance
Instead of using /dev/ttyUSB* devices, write udev rules to generate named symlinks to the devices. For a brief how-to, see here. Basically, you'll have an udev rule for each device, ending with say SYMLINK+=Sensor-name, and in your program, use /dev/Sensor-name for each sensor. (I do recommend using Sensor- prefix, noting the initial Capital letter, as all device names are currently lowercase. This avoids any clashes with existing devices.)
These symlinks will then only exist when the matching device is plugged in, and will point to the correct device (/dev/ttyUSB* in this case). When the device is removed, udev automagically deletes the symlink also. Just make sure your udev rule identifies the device precisely (not just vendor:device, but serial number also). I'd expect the rule to look something like
SUBSYSTEM=="tty", ATTRS{idVendor}=="VVVV", ATTRS{idProduct}=="PPPP", ATTRS{serial}=="SSSSSSSS", SYMLINK+="Sensor-name"
where VVVV is the USB Vendor ID (four hexadecimal digits), PPPP is the USB Product ID (four hexadecimal digits), and SSSSSSSS is the serial number string. You can see these values using e.g. udevadm info -a -n /dev/ttyUSB* when the device is plugged in.
If you still insist on parsing dmesg output, using your own script is a good idea.
You could use FILE *handle = popen("dmesg | find_usb.py", "r"); and read from handle like it was a file. When complete, close the handle using int exitstatus = pclose(handle);. See man popen and man pclose for the details, and man 2 wait for the WIFEXITED(), WEXITSTATUS(), WIFSIGNALED(), WTERMSIG() macros you'll need to use to examine exitstatus (although in your case, I suppose you can just ignore any errors).
If you do want to use posix_spawn() (or roughly equivalently, fork() and execvp()), you'd need to set up at least one pipe (to read the output of the spawned command) – two if you spawn/fork+exec both dmesg and your Python script –, and that gets a bit more complicated. See man pipe for details on that. Personally, I would rewrite the Python script so that it executes dmesg itself internally, and only outputs the device name(s). With posix_spawn(), you'd init a posix_file_actions_t, with three actions: _adddup2() to duplicate the write end of the pipe to STDOUT_FILENO, and two _addclose()s to close both ends of the pipe. However, I myself prefer to use fork() and exec() instead, somewhat similar to the example by Glärbo in this answer.
I am using Linux LGs and I want to use syslog / rsyslog to dump the custom logs from my loadrunner vugen script. For that I tried to run a linux command by using the loadrunner function int system( const char *string); but it's not working for me. Do you have any alternative for this?
For your ready reference please check the custom function which I have used for using the syslog / rsyslog.
lr_syslog(char *log)
{
lr_param_sprintf("PAR_syslog", lr_eval_string("./syslog %s"), log );
system(lr_eval_string("{PAR_syslog}"));
return 0;
}
and syslog.c is as follows
#include <syslog.h>
void main(int argc, char *argv[])
{
openlog ("loadrunner", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
syslog (LOG_INFO, "customlog - %s", argv[1] );
closelog ();
}
Thanks in advance.
May I suggest as an alternative the use or lr_output_message() which will be directed to the output window on your controller.
If you wish to post process these messages in logparser, elk, or splunk you can then export the messages and import them into your favored log analysis tool..... or you can just use the features of Microsoft Access to run queries against the messages using standard SQL.
I suggest that you could collect system log while perform testing. After tested, you could open test result by LR Analysis and import system log by Import Data function.
Then you could create Correlation between Response Time and system resource in LR Analysis. And it will help you to analyze performance.
From this URL,you could find the detailed usage of Import Data.
Ok so I am having problems with syslog on Raspbian Stretch. I am trying to write to /var/log/blah.log using local0 as my facility. I am using gnu C++ 11 As the application is being written in C++ so I trying to create a logging class.
My /etc/syslog.conf has the following entry
local0.* /var/log/blah.log
... and I have restarted the service and the Pi.
My code to open the log is as follows:
setlogmask(LOG_UPTO(LOG_DEBUG));
openlog(blah, LOG_PERROR | LOG_CONS | LOG_NDELAY, LOG_LOCAL0);
...and my logging code is:
syslog(LOG_INFO | LOG_LOCAL0, fullMessage.c_str());
There is no /var/log/blah.log file created and no log entries written, although the message is written to the console as I am using LOG_CONS.
If I replace LOG_LOCAL0 with LOG_USER I am successfully able write to user.log.
I do want to be able to write to the custom log file because:
a) it is easy to ask a user to look at that file for debugging purposes
b) it should work!!
As I have stated I have looked through the numerous posts on this site and others and still cannot get it top work so posting links to man pages and other articles won't help!
I have an application that uses syslog for logging. another library within this application explicitly calls openlog() for its own usage, in this case something strange happens: stderr output is sent to a tcp socket I already opened.
When I change the lib's output log to stderr or stdout everything works fine.
I was wondering if this a problem with two syslog connection or is it just a mess-up somewhere in the code?
This is syslog initialisation of the main app:
openlog( "app", LOG_PID|LOG_NDELAY, LOG_LOCAL1 );
This is syslog initialisation of the lib:
openlog("lib", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
It is probably implementation dependent. If you use MUSL libc the code is here in syslog.c an you can see that only one fd is used for syslog (so two openlog-s are sharing the same log_fd). Look into GNU libc source code to see what happens on most Linux implementations. You might also investigate with strace or ltrace
I wrote a simple test application to log something in a log file. I am using linux mint and after the application executes I try to view the log using this command:
tail -n 100 /var/log/messages
but the file messages does not exist neither tested or something. Below you can find my code. Maybe I am doing something wrong, the file isn't stored there or I need to enable logging in linux mint.
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
void init_log()
{
setlogmask(LOG_UPTO(LOG_NOTICE));
openlog("testd",LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
}
int main(void) {
init_log();
printf("Session started!");
syslog(LOG_NOTICE, "Session started!!");
closelog();
return EXIT_SUCCESS;
}
On my Ubuntu machine, I can see the output at /var/log/syslog.
On a RHEL/CentOS machine, the output is found in /var/log/messages.
This is controlled by the rsyslog service, so if this is disabled for some reason you may need to start it with systemctl start rsyslog.
As noted by others, your syslog() output would be logged by the /var/log/syslog file.
You can see system, user, and other logs at /var/log.
For more details: here's an interesting link.
Default log location (rhel) are
General messages:
/var/log/messages
Authentication messages:
/var/log/secure
Mail events:
/var/log/maillog
Check your /etc/syslog.conf or /etc/syslog-ng.conf (it depends on which of syslog facility you have installed)
Example:
$ cat /etc/syslog.conf
# Log anything (except mail) of level info or higher.
# Don't log private authentication messages!
*.info;mail.none;authpriv.none /var/log/messages
# The authpriv file has restricted access.
authpriv.* /var/log/secure
# Log all the mail messages in one place.
mail.* /var/log/maillog
#For a start, use this simplified approach.
*.* /var/log/messages
In addition to the accepted answer, it is useful to know the following ...
Each of those functions should have manual pages associated with them.
If you run man -k syslog (a keyword search of man pages) you will get a list of man pages that refer to, or are about syslog
$ man -k syslog
logger (1) - a shell command interface to the syslog(3) system l...
rsyslog.conf (5) - rsyslogd(8) configuration file
rsyslogd (8) - reliable and extended syslogd
syslog (2) - read and/or clear kernel message ring buffer; set c...
syslog (3) - send messages to the system logger
vsyslog (3) - send messages to the system logger
You need to understand the manual sections in order to delve further.
Here's an excerpt from the man page for man, that explains man page sections :
The table below shows the section numbers of the manual followed by
the types of pages they contain.
1 Executable programs or shell commands
2 System calls (functions provided by the kernel)
3 Library calls (functions within program libraries)
4 Special files (usually found in /dev)
5 File formats and conventions eg /etc/passwd
6 Games
7 Miscellaneous (including macro packages and conven‐
tions), e.g. man(7), groff(7)
8 System administration commands (usually only for root)
9 Kernel routines [Non standard]
To read the above run
$man man
So, if you run man 3 syslog you get a full manual page for the syslog function that you called in your code.
SYSLOG(3) Linux Programmer's Manual SYSLOG(3)
NAME
closelog, openlog, syslog, vsyslog - send messages to the system
logger
SYNOPSIS
#include <syslog.h>
void openlog(const char *ident, int option, int facility);
void syslog(int priority, const char *format, ...);
void closelog(void);
#include <stdarg.h>
void vsyslog(int priority, const char *format, va_list ap);
Not a direct answer but hopefully you will find this useful.
You have to tell the system what information to log and where to put the info. Logging is configured in the /etc/rsyslog.conf file, then restart rsyslog to load the new config. The default logging rules are usually in a /etc/rsyslog.d/50-default.conf file.
syslog() generates a log message, which will be distributed by syslogd.
The file to configure syslogd is /etc/syslog.conf.
This file will tell your where the messages are logged.
How to change options in this file ?
Here you go
http://www.bo.infn.it/alice/alice-doc/mll-doc/duix/admgde/node74.html
Logging is very configurable in Linux, and you might want to look into your /etc/syslog.conf (or perhaps under /etc/rsyslog.d/). Details depend upon the logging subsystem, and the distribution.
Look also into files under /var/log/ (and perhaps run dmesg for kernel logs).
I'm running Ubuntu under WSL(Windows Subsystem for Linux) and systemctl start rsyslog didn't work for me.
So what I did is this:
$ service rsyslog start
Now syslog file will appear at /var/log/