Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement enhanced logging using journald/asld #4474

Closed
michaelrsweet opened this issue Aug 25, 2014 · 12 comments
Closed

Implement enhanced logging using journald/asld #4474

michaelrsweet opened this issue Aug 25, 2014 · 12 comments
Labels
enhancement New feature or request
Milestone

Comments

@michaelrsweet
Copy link
Collaborator

Version: 2.1-feature
CUPS.org User: mike

OS X supports an enhanced logging API that replaces syslogd. Linux has journald. We should adopt support for enhanced logging using the PWG Common Log Format (PWG5110.3) syslog attributes.

From Tim Waugh:

Hi,

I've attached the patch I've been using for CUPS 1.7.x to get it to log
to the systemd journal, so you can see the approach I've taken. As I
mentioned last week we could get better logging if we used a macro for
cupsdLog*, as that way the source module and line number would also be
logged accurately.

The meat of it is this bit:

  • if (job)
  • {
  •  return (sd_journal_send ("MESSAGE=%s", message,
    
  •                          "PRIORITY=%d", syslevels[level],
    
  •                          "CUPS_JOB_ID=%d", job->id,
    
  •                          NULL) ? 0 : 1);
    
  • } else
  •  return (sd_journal_print (syslevels[level], "%s", message) ? 0 : 1);
    

Logs that result from this end up with these fields:

Fri 2014-08-22 16:51:59.000990 BST [s=0b751e71c5ee4016aca9741c09de1025;i=136c1;b=0881631c8e944c36b324de9a54962491;m=207b0832a;t=50139d140d09b;x=bf1d64cb10934e6a]
PRIORITY=6
_UID=0
_GID=0
_SYSTEMD_SLICE=system.slice
_MACHINE_ID=971a1791404d4754ba16b87fa6db358e
_HOSTNAME=localhost.localdomain
_TRANSPORT=journal
_CAP_EFFECTIVE=3fffffffff
CODE_FILE=log.c
SYSLOG_IDENTIFIER=cupsd
_COMM=cupsd
_EXE=/usr/sbin/cupsd
_CMDLINE=/usr/sbin/cupsd -f
_SYSTEMD_CGROUP=/system.slice/cups.service
_SYSTEMD_UNIT=cups.service
_SELINUX_CONTEXT=system_u:system_r:cupsd_t:s0-s0:c0.c1023
_PID=687
_BOOT_ID=0881631c8e944c36b324de9a54962491
CODE_LINE=572
CODE_FUNC=cupsdLogJob
MESSAGE=[Job 2] Adding start banner page "none".
CUPS_JOB_ID=2
_SOURCE_REALTIME_TIMESTAMP=1408722719000990

Fields beginning with "_" are put in by journald (and so can be trusted
to be reliable). Other fields are provided by the application logging
the message. There is more information about them here:
http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html

The only one I've added is CUPS_JOB_ID, but even the default set of
fields gives some useful information for pinpointing/diagnosing
interesting log messages.

Another potentially interesting one is MESSAGE_ID.

I see from developments since 1.7.x that you've got separate functions
for logging messages related to different objects, so that's great.

I'd love to bring the journal support into line with identifiers you are
using for OS X logging.

Tim.
*/

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: twaugh.redhat

Is this meant to be private?

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Nope, should be public...

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: thx1138

On Arch Linux, cups 2.0.0-2, in the testing repository, as patched:
https://projects.archlinux.org/svntogit/packages.git/tree/trunk?h=packages/cups

running "systemctl -n status org.cups.cupsd.service", the last lines of the cupsd entries in the journal do not show in the status output. This, despite the systemctl man page status command description, promising "followed by most recent log data from the journal".

Is this a "systemctl status" problem? Or could this be caused by the way cupsd is logging to the journal?

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: twaugh.redhat

Here's an updated patch against master. It includes accurate CODE_FILE, CODE_LINE, and CODE_FUNC fields, as well as additional fields CUPS_DEST and CUPS_PRINTER.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

OK, just finished the ASL stuff. Next up is the journald support, followed by some cleanup.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Fixed in Subversion repository.

@michaelrsweet
Copy link
Collaborator Author

"cups-journal.patch":

diff -up cups-1.7.1/config.h.in.journal cups-1.7.1/config.h.in
--- cups-1.7.1/config.h.in.journal 2014-02-17 16:48:19.089795987 +0000
+++ cups-1.7.1/config.h.in 2014-02-17 16:48:19.136796218 +0000
@@ -458,6 +458,13 @@

/*

  • * Do we have systemd-journal support?
  • /
    +
    +#undef HAVE_JOURNAL
    +
    +
    +/
    • Various scripting languages...
      */

diff -up cups-1.7.1/config-scripts/cups-systemd.m4.journal cups-1.7.1/config-scripts/cups-systemd.m4
--- cups-1.7.1/config-scripts/cups-systemd.m4.journal 2014-02-17 16:48:19.089795987 +0000
+++ cups-1.7.1/config-scripts/cups-systemd.m4 2014-02-17 16:48:19.136796218 +0000
@@ -22,6 +22,15 @@ if test "x$with_systemdsystemunitdir" !=
fi
fi

+SDJLIBS=""
+AC_MSG_CHECKING(for libsystemd-journal)
+if $PKGCONFIG --exists libsystemd-journal; then

  • AC_MSG_RESULT(yes)
  • SDJLIBS=$PKGCONFIG --libs libsystemd-journal
  • AC_DEFINE(HAVE_JOURNAL)
    +else
  • AC_MSG_RESULT(no)
    +fi
    if test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ; then
    SYSTEMD_UNITS="cups.service cups.socket cups.path"
    else
    @@ -30,6 +39,7 @@ fi

AC_SUBST(SYSTEMD_UNITS)
AC_SUBST(SDLIBS)
+AC_SUBST(SDJLIBS)

dnl
dnl "$Id$"
diff -up cups-1.7.1/doc/help/ref-cups-files-conf.html.in.journal cups-1.7.1/doc/help/ref-cups-files-conf.html.in
--- cups-1.7.1/doc/help/ref-cups-files-conf.html.in.journal 2014-02-17 17:06:11.652078495 +0000
+++ cups-1.7.1/doc/help/ref-cups-files-conf.html.in 2014-02-17 17:11:50.675752398 +0000
@@ -18,6 +18,7 @@
AccessLog /var/log/cups/access_log
AccessLog /var/log/cups/access_log-%s
AccessLog syslog
+AccessLog journal

Description

@@ -36,6 +37,9 @@ server activity.

The special name "syslog" can be used to send the access information to the system log instead of a plain file.

+

The special name "journal" can be used to send the access
+information to the system log instead of a plain file.


+

The default access log file is /var/log/access_log.

@@ -108,6 +112,7 @@ language needed.


ErrorLog /var/log/cups/error_log
ErrorLog /var/log/cups/error_log-%s
ErrorLog syslog
+ErrorLog journal

Description

@@ -124,6 +129,11 @@ default error log file is /var/log/

The special name "syslog" can be used to send the error information to the system log instead of a plain file.

+

The special name "journal" can be used to send the error
+information to the system journal instead of a plain file. Information
+relating to a specific job is logged with the field
+CUPS_JOB_ID filled in.


+

CUPS 1.4/OS X 10.6FatalErrors

@@ -266,6 +276,7 @@ is 644.


PageLog /var/log/cups/page_log
PageLog /var/log/cups/page_log-%s
PageLog syslog
+PageLog journal

Description

@@ -282,6 +293,11 @@ default page log file is /var/log/c

The special name "syslog" can be used to send the page information to the system log instead of a plain file.

+

The special name "journal" can be used to send the page information
+to the system journal instead of a plain file. The fields
+CUPS_JOB_ID and CUPS_PAGE_NUMBER will be
+filled in.


+

Printcap

diff -up cups-1.7.1/Makedefs.in.journal cups-1.7.1/Makedefs.in
--- cups-1.7.1/Makedefs.in.journal 2014-02-17 16:48:19.090795992 +0000
+++ cups-1.7.1/Makedefs.in 2014-02-17 16:48:19.136796218 +0000
@@ -143,6 +143,7 @@ IPPFIND_BIN = @IPPFIND_BIN@
IPPFIND_MAN = @IPPFIND_MAN@
LAUNCHDLIBS = @LAUNCHDLIBS@
SDLIBS = @SDLIBS@
+SDJLIBS = @SDJLIBS@
LDFLAGS = -L../cgi-bin -L../cups -L../filter -L../ppdc
-L../scheduler @LDARCHFLAGS@
@LDFLAGS@ @RELROFLAGS@ @PIEFLAGS@ $(OPTIM)
diff -up cups-1.7.1/man/cups-files.conf.man.in.journal cups-1.7.1/man/cups-files.conf.man.in
--- cups-1.7.1/man/cups-files.conf.man.in.journal 2014-02-17 17:05:08.103764935 +0000
+++ cups-1.7.1/man/cups-files.conf.man.in 2014-02-17 17:06:48.131258521 +0000
@@ -29,6 +29,8 @@ on-line help for detailed descriptions:
AccessLog filename
.TP 5
AccessLog syslog
+.TP 5
+AccessLog journal
.br
Defines the access log filename.
.TP 5
@@ -48,6 +50,8 @@ Specifies the root directory for the int
ErrorLog filename
.TP 5
ErrorLog syslog
+.TP 5
+ErrorLog journal
.br
Specifies the error log filename.
.TP 5
@@ -83,6 +87,8 @@ Specifies the permissions for all log fi
PageLog filename
.TP 5
PageLog syslog
+.TP 5
+PageLog journal
.br
Specifies the page log filename.
.TP 5
diff -up cups-1.7.1/scheduler/conf.c.journal cups-1.7.1/scheduler/conf.c
--- cups-1.7.1/scheduler/conf.c.journal 2014-02-17 16:48:19.047795781 +0000
+++ cups-1.7.1/scheduler/conf.c 2014-02-17 16:48:19.137796223 +0000
@@ -950,9 +950,9 @@ cupsdReadConfiguration(void)
*/

#ifdef HAVE_VSYSLOG

  • if (!strcmp(AccessLog, "syslog") ||
  •  !strcmp(ErrorLog, "syslog") ||
    
  •  !strcmp(PageLog, "syslog"))
    
  • if (!strcmp(AccessLog, "syslog") || !strcmp(AccessLog, "journal") ||
  •  !strcmp(ErrorLog, "syslog") || !strcmp(ErrorLog, "journal") ||
    
  •  !strcmp(PageLog, "syslog") || !strcmp(PageLog, "journal"))
    
    openlog("cupsd", LOG_PID | LOG_NOWAIT | LOG_NDELAY, LOG_LPR);
    #endif /* HAVE_VSYSLOG */

@@ -960,13 +960,13 @@ cupsdReadConfiguration(void)

  • Make sure each of the log files exists and gets rotated as necessary...
    */
  • if (strcmp(AccessLog, "syslog"))
  • if (strcmp(AccessLog, "syslog") && strcmp(AccessLog, "journal"))
    cupsdCheckLogFile(&AccessFile, AccessLog);
  • if (strcmp(ErrorLog, "syslog"))
  • if (strcmp(ErrorLog, "syslog") && strcmp(ErrorLog, "journal"))
    cupsdCheckLogFile(&ErrorFile, ErrorLog);
  • if (strcmp(PageLog, "syslog"))
  • if (strcmp(PageLog, "syslog") && strcmp(PageLog, "journal"))
    cupsdCheckLogFile(&PageFile, PageLog);

/*
diff -up cups-1.7.1/scheduler/conf.h.journal cups-1.7.1/scheduler/conf.h
--- cups-1.7.1/scheduler/conf.h.journal 2014-02-17 16:48:19.048795786 +0000
+++ cups-1.7.1/scheduler/conf.h 2014-02-17 16:48:19.138796228 +0000
@@ -297,6 +297,8 @@ extern int cupsdLogMessage(int level, co
extern int cupsdLogPage(cupsd_job_t *job, const char *page);
extern int cupsdLogRequest(cupsd_client_t *con, http_status_t code);
extern int cupsdReadConfiguration(void);
+extern int cupsdWriteErrorLogJob(cupsd_job_t *job, int level,

  •                 const char *message);
    
    extern int cupsdWriteErrorLog(int level, const char *message);

diff -up cups-1.7.1/scheduler/log.c.journal cups-1.7.1/scheduler/log.c
--- cups-1.7.1/scheduler/log.c.journal 2014-02-17 16:48:19.073795909 +0000
+++ cups-1.7.1/scheduler/log.c 2014-02-17 16:48:19.138796228 +0000
@@ -21,6 +21,7 @@

  • cupsdLogMessage() - Log a message to the error log file.
  • cupsdLogPage() - Log a page to the page log file.
  • cupsdLogRequest() - Log an HTTP request in Common Log Format.
  • * cupsdWriteErrorLogJob() - Write a job message to the ErrorLog.
  • cupsdWriteErrorLog() - Write a line to the ErrorLog.
  • format_log_line() - Format a line for a log file.
    /
    @@ -35,6 +36,9 @@
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    +#ifdef HAVE_JOURNAL
    +# include <systemd/sd-journal.h>
    +#endif /
    HAVE_JOURNAL */

/*
@@ -559,8 +563,17 @@ cupsdLogJob(cupsd_job_t job, / I - Jo
}
else if (level <= LogLevel &&
(level != CUPSD_LOG_INFO || LogLevel >= CUPSD_LOG_DEBUG))

  •  return (cupsdWriteErrorLog(level, log_line));
    
  • else
  • {
  •  if (!strcmp (ErrorLog, "journal"))
    
    +#ifdef HAVE_JOURNAL
  • return (sd_journal_send ("MESSAGE=%s", log_line,
  •            "PRIORITY=%d", syslevels[level],
    
  •            "CUPS_JOB_ID=%d", job ? job->id : -1,
    
  •            NULL)) ? 0 : 1;
    
  •  else
    
    +#endif /* HAVE_JOURNAL */
  • return (cupsdWriteErrorLog(level, log_line));
  • } else
    return (1);
    }
    else
    @@ -789,6 +802,15 @@ cupsdLogPage(cupsd_job_t job, / I - J

*bufptr = '\0';

+#ifdef HAVE_JOURNAL

  • if (!strcmp(PageLog, "journal"))

  • return (sd_journal_send ("MESSAGE=%s", buffer,

  •            "PRIORITY=%d", LOG_INFO,
    
  •            "CUPS_JOB_ID=%d", job->id,
    
  •            "CUPS_PAGE_NUMBER=%s", number,
    
  •            NULL) ? 0 : 1);
    

    +#endif /* HAVE_JOURNAL /
    +
    #ifdef HAVE_VSYSLOG
    /

    • See if we are logging pages via syslog...
      @@ -964,7 +986,7 @@ cupsdLogRequest(cupsd_client_t con, /
    • See if we are logging accesses via syslog...
      */
  • if (!strcmp(AccessLog, "syslog"))

  • if (!strcmp(AccessLog, "syslog") || !strcmp(AccessLog, "journal"))
    {
    syslog(LOG_INFO,
    "REQUEST %s - %s "%s %s HTTP/%d.%d" %d " CUPS_LLFMT " %s %s\n",
    @@ -1018,8 +1040,9 @@ cupsdLogRequest(cupsd_client_t con, /
    */

int /* O - 1 on success, 0 on failure /
-cupsdWriteErrorLog(int level, /
I - Log level */

  •               const char _message)    /_ I - Message string _/
    
    +cupsdWriteErrorLogJob(cupsd_job_t *job, /_ I - Job or NULL */
  •         int          level, /\* I - Log level */
    
  •         const char  _message) /_ I - Message string _/
    
    {
    static const char levels[] = /_ Log levels... /
    {
    @@ -1036,12 +1059,25 @@ cupsdWriteErrorLog(int level, /

    };

+#ifdef HAVE_JOURNAL

  • if (!strcmp(ErrorLog, "journal"))
  • {
  • if (job)
  • {
  •  return (sd_journal_send ("MESSAGE=%s", message,
    
  •              "PRIORITY=%d", syslevels[level],
    
  •              "CUPS_JOB_ID=%d", job->id,
    
  •              NULL) ? 0 : 1);
    
  • } else
  •  return (sd_journal_print (syslevels[level], "%s", message) ? 0 : 1);
    
  • }
    +#endif /* HAVE_JOURNAL /
    #ifdef HAVE_VSYSLOG
    /
  • See if we are logging errors via syslog...
    */
  • if (!strcmp(ErrorLog, "syslog"))
  • if (!strcmp(ErrorLog, "syslog") || !strcmp(ErrorLog, "journal"))
    {
    syslog(syslevels[level], "%s", message);
    return (1);
    @@ -1067,6 +1103,18 @@ cupsdWriteErrorLog(int level, /*
    }

+/*

  • * 'cupsdWriteErrorLog()' - Write a line to the ErrorLog.
  • /
    +
    +int /
    O - 1 on success, 0 on failure /
    +cupsdWriteErrorLog(int level, /
    I - Log level */
  •      const char  _message) /_ I - Message string */
    
    +{
  • return (cupsdWriteErrorLogJob(NULL, level, message));
    +}

/*

  • 'format_log_line()' - Format a line for a log file.
    *
    diff -up cups-1.7.1/scheduler/Makefile.journal cups-1.7.1/scheduler/Makefile
    --- cups-1.7.1/scheduler/Makefile.journal 2014-02-17 16:48:19.124796159 +0000
    +++ cups-1.7.1/scheduler/Makefile 2014-02-17 16:48:19.137796223 +0000
    @@ -383,7 +383,7 @@ cupsd: $(CUPSDOBJS) $(LIBCUPSMIME) ../cu
    $(CC) $(LDFLAGS) -o cupsd $(CUPSDOBJS) -L. -lcupsmime
    $(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS)
    $(LIBPAPER) $(LIBMALLOC) $(SERVERLIBS) $(DNSSDLIBS) $(LIBS) \

  •   $(LIBGSSAPI) $(LIBWRAP) $(SDLIBS)
    
  •   $(LIBGSSAPI) $(LIBWRAP) $(SDLIBS) $(SDJLIBS)
    

    cupsd-static: $(CUPSDOBJS) libcupsmime.a ../cups/$(LIBCUPSSTATIC)
    echo Linking $@...
    @@ -391,7 +391,7 @@ cupsd-static: $(CUPSDOBJS) libcupsmime.a
    $(LIBZ) $(SSLLIBS) $(LIBSLP) $(LIBLDAP) $(PAMLIBS)
    ../cups/$(LIBCUPSSTATIC) $(COMMONLIBS) $(LIBZ) $(LIBPAPER)
    $(LIBMALLOC) $(SERVERLIBS) $(DNSSDLIBS) $(LIBGSSAPI) \

  •   $(LIBWRAP)  $(SDLIBS)
    
  •   $(LIBWRAP)  $(SDLIBS) $(SDJLIBS)
    

    tls.o: tls-darwin.c tls-gnutls.c tls-openssl.c

--- cups-1.7.1/conf/cups-files.conf.in.journal 2014-04-04 13:12:13.923185140 +0100
+++ cups-1.7.1/conf/cups-files.conf.in 2014-04-04 13:13:10.633430876 +0100
@@ -30,9 +30,10 @@ SystemGroup @CUPS_SYSTEM_GROUPS@
#ConfigFilePerm 0@CUPS_CONFIG_FILE_PERM@
#LogFilePerm 0@CUPS_LOG_FILE_PERM@

-# Location of the file logging all access to the scheduler; may be the name
-# "syslog". If not an absolute path, the value of ServerRoot is used as the
-# root directory. Also see the "AccessLogLevel" directive in cupsd.conf.
+# Location of the file logging all access to the scheduler; may be the
+# name "syslog" or "journal". If not an absolute path, the value of
+# ServerRoot is used as the root directory. Also see the
+# "AccessLogLevel" directive in cupsd.conf.
AccessLog @CUPS_LOGDIR@/access_log

Location of cache files used by the scheduler...

@@ -44,10 +45,10 @@ AccessLog @CUPS_LOGDIR@/access_log

Location of the static web content served by the scheduler...

#DocumentRoot @CUPS_DOCROOT@

-# Location of the file logging all messages produced by the scheduler and any
-# helper programs; may be the name "syslog". If not an absolute path, the value
-# of ServerRoot is used as the root directory. Also see the "LogLevel"
-# directive in cupsd.conf.
+# Location of the file logging all messages produced by the scheduler
+# and any helper programs; may be the name "syslog" or "journal". If
+# not an absolute path, the value of ServerRoot is used as the root
+# directory. Also see the "LogLevel" # directive in cupsd.conf.
ErrorLog @CUPS_LOGDIR@/error_log

Location of fonts used by older print filters...

@@ -56,10 +57,10 @@ ErrorLog @CUPS_LOGDIR@/error_log

Location of LPD configuration

#LPDConfigFile @CUPS_DEFAULT_LPD_CONFIG_FILE@

-# Location of the file logging all pages printed by the scheduler and any
-# helper programs; may be the name "syslog". If not an absolute path, the value
-# of ServerRoot is used as the root directory. Also see the "PageLogFormat"
-# directive in cupsd.conf.
+# Location of the file logging all pages printed by the scheduler and
+# any helper programs; may be the name "syslog" or "journal". If not
+# an absolute path, the value of ServerRoot is used as the root
+# directory. Also see the "PageLogFormat" directive in cupsd.conf.
PageLog @CUPS_LOGDIR@/page_log

Location of the file listing all of the local printers...

@michaelrsweet
Copy link
Collaborator Author

"0001-Support-for-logging-to-the-systemd-journal-STR-4474.patch":

From c42e823114ca7bf3e9ff24e32c5940541213b4f4 Mon Sep 17 00:00:00 2001
From: Tim Waugh twaugh@redhat.com
Date: Thu, 6 Nov 2014 12:51:51 +0000
Subject: [PATCH] Support for logging to the systemd journal (STR #4474).


conf/cups-files.conf.in | 23 +++--
config-scripts/cups-startup.m4 | 8 +-
doc/help/man-cups-files.conf.html | 3 +
man/cups-files.conf.man.in | 18 +++-
scheduler/conf.c | 12 +--
scheduler/conf.h | 63 +++++++++++-
scheduler/log.c | 204 ++++++++++++++++++++++++++++++++++----
7 files changed, 285 insertions(+), 46 deletions(-)

diff --git a/conf/cups-files.conf.in b/conf/cups-files.conf.in
index 71683a6..e341225 100644
--- a/conf/cups-files.conf.in
+++ b/conf/cups-files.conf.in
@@ -29,9 +29,10 @@ SystemGroup @CUPS_SYSTEM_GROUPS@
#ConfigFilePerm 0@CUPS_CONFIG_FILE_PERM@
#LogFilePerm 0@CUPS_LOG_FILE_PERM@

-# Location of the file logging all access to the scheduler; may be the name
-# "syslog". If not an absolute path, the value of ServerRoot is used as the
-# root directory. Also see the "AccessLogLevel" directive in cupsd.conf.
+# Location of the file logging all access to the scheduler; may be the
+# name "syslog" or "journal". If not an absolute path, the value of
+# ServerRoot is used as the root directory. Also see the
+# "AccessLogLevel" directive in cupsd.conf.
AccessLog @CUPS_LOGDIR@/access_log

Location of cache files used by the scheduler...

@@ -43,10 +44,10 @@ AccessLog @CUPS_LOGDIR@/access_log

Location of the static web content served by the scheduler...

#DocumentRoot @CUPS_DOCROOT@

-# Location of the file logging all messages produced by the scheduler and any
-# helper programs; may be the name "syslog". If not an absolute path, the value
-# of ServerRoot is used as the root directory. Also see the "LogLevel"
-# directive in cupsd.conf.
+# Location of the file logging all messages produced by the scheduler
+# and any helper programs; may be the name "syslog" or "journal". If
+# not an absolute path, the value of ServerRoot is used as the root
+# directory. Also see the "LogLevel" # directive in cupsd.conf.
ErrorLog @CUPS_LOGDIR@/error_log

Location of fonts used by older print filters...

@@ -55,10 +56,10 @@ ErrorLog @CUPS_LOGDIR@/error_log

Location of LPD configuration

#LPDConfigFile @CUPS_DEFAULT_LPD_CONFIG_FILE@

-# Location of the file logging all pages printed by the scheduler and any
-# helper programs; may be the name "syslog". If not an absolute path, the value
-# of ServerRoot is used as the root directory. Also see the "PageLogFormat"
-# directive in cupsd.conf.
+# Location of the file logging all pages printed by the scheduler and
+# any helper programs; may be the name "syslog" or "journal". If not
+# an absolute path, the value of ServerRoot is used as the root
+# directory. Also see the "PageLogFormat" directive in cupsd.conf.
PageLog @CUPS_LOGDIR@/page_log

Location of the file listing all of the local printers...

diff --git a/config-scripts/cups-startup.m4 b/config-scripts/cups-startup.m4
index d48ab9d..2580fd4 100644
--- a/config-scripts/cups-startup.m4
+++ b/config-scripts/cups-startup.m4
@@ -56,11 +56,11 @@ if test x$enable_systemd != xno; then
AC_MSG_ERROR(Need pkg-config to enable systemd support.)
fi
else

  •       AC_MSG_CHECKING(for libsystemd-daemon)
    
  •            if $PKGCONFIG --exists libsystemd-daemon; then
    
  •   AC_MSG_CHECKING(for libsystemd)
    
  •            if $PKGCONFIG --exists libsystemd; then
                     AC_MSG_RESULT(yes)
    
  •                    ONDEMANDFLAGS=`$PKGCONFIG --cflags libsystemd-daemon`
    
  •                    ONDEMANDLIBS=`$PKGCONFIG --libs libsystemd-daemon`
    
  •                    ONDEMANDFLAGS=`$PKGCONFIG --cflags libsystemd`
    
  •                    ONDEMANDLIBS=`$PKGCONFIG --libs libsystemd`
                     AC_DEFINE(HAVE_SYSTEMD)
        if test "x$SYSTEMD_DIR" = x; then
                SYSTEMD_DIR="`$PKGCONFIG --variable=systemdsystemunitdir systemd`"
    
    diff --git a/doc/help/man-cups-files.conf.html b/doc/help/man-cups-files.conf.html
    index 2c3caa2..8602943 100644
    --- a/doc/help/man-cups-files.conf.html
    +++ b/doc/help/man-cups-files.conf.html
    @@ -24,6 +24,7 @@ The following directives are understood by
    AccessLog
    AccessLog filename
    AccessLog syslog +
    AccessLog journal
    Defines the access log filename. Specifying a blank filename disables access log generation. The value "syslog" causes log entries to be sent to the system log daemon. @@ -51,6 +52,7 @@ The default is usually "/usr/share/doc/cups".
    ErrorLog
    ErrorLog filename
    ErrorLog syslog +
    ErrorLog journal
    Defines the error log filename. Specifying a blank filename disables error log generation. The value "syslog" causes log entries to be sent to the system log daemon. @@ -96,6 +98,7 @@ The default group is operating system specific but is usually "lp" or "nobody". The default is "0644".
    PageLog [ filename ]
    PageLog syslog +
    PageLog journal
    Defines the page log filename. The value "syslog" causes log entries to be sent to the system log daemon. Specifying a blank filename disables page log generation. diff --git a/man/cups-files.conf.man.in b/man/cups-files.conf.man.in index 2e09bef..8f8953b 100644 --- a/man/cups-files.conf.man.in +++ b/man/cups-files.conf.man.in @@ -33,9 +33,13 @@ The following directives are understood by \fBAccessLog \fIfilename\fR .TP 5 \fBAccessLog syslog\fR +.TP 5 +\fBAccessLog journal\fR Defines the access log filename. Specifying a blank filename disables access log generation. -The value "syslog" causes log entries to be sent to the system log daemon. +The value "syslog" causes log entries to be sent to the system log +daemon. The value "journal" causes log entries to be sent to the +systemd journal. The server name may be included in filenames using the string "%s", for example: .nf

@@ -65,9 +69,13 @@ The default is usually "/usr/share/doc/cups".
\fBErrorLog \fIfilename\fR
.TP 5
\fBErrorLog syslog\fR
+.TP 5
+\fBErrorLog journal\fR
Defines the error log filename.
Specifying a blank filename disables error log generation.
-The value "syslog" causes log entries to be sent to the system log daemon.
+The value "syslog" causes log entries to be sent to the system log
+daemon. The value "journal" causes log entries to be sent to the
+systemd journal.
The server name may be included in filenames using the string "%s", for example:
.nf

@@ -125,8 +133,12 @@ The default is "0644".
\fBPageLog \fR[ \fIfilename\fR ]
.TP 5
\fBPageLog syslog\fR
+.TP 5
+\fBPageLog journal\fR
Defines the page log filename.
-The value "syslog" causes log entries to be sent to the system log daemon.
+The value "syslog" causes log entries to be sent to the system log
+daemon. The value "journal" causes log entries to be sent to the
+systemd journal.
Specifying a blank filename disables page log generation.
The server name may be included in filenames using the string "%s", for example:
.nf
diff --git a/scheduler/conf.c b/scheduler/conf.c
index 9f22b40..596413a 100644
--- a/scheduler/conf.c
+++ b/scheduler/conf.c
@@ -949,9 +949,9 @@ cupsdReadConfiguration(void)
*/

#ifdef HAVE_VSYSLOG

  • if (!strcmp(AccessLog, "syslog") ||
  •  !strcmp(ErrorLog, "syslog") ||
    
  •  !strcmp(PageLog, "syslog"))
    
  • if (!strcmp(AccessLog, "syslog") || !strcmp(AccessLog, "journal") ||
  •  !strcmp(ErrorLog, "syslog") || !strcmp(ErrorLog, "journal") ||
    
  •  !strcmp(PageLog, "syslog") || !strcmp(PageLog, "journal"))
    
    openlog("cupsd", LOG_PID | LOG_NOWAIT | LOG_NDELAY, LOG_LPR);
    #endif /* HAVE_VSYSLOG */

@@ -959,13 +959,13 @@ cupsdReadConfiguration(void)

  • Make sure each of the log files exists and gets rotated as necessary...
    */
  • if (strcmp(AccessLog, "syslog"))
  • if (strcmp(AccessLog, "syslog") && strcmp(AccessLog, "journal"))
    cupsdCheckLogFile(&AccessFile, AccessLog);
  • if (strcmp(ErrorLog, "syslog"))
  • if (strcmp(ErrorLog, "syslog") && strcmp(ErrorLog, "journal"))
    cupsdCheckLogFile(&ErrorFile, ErrorLog);
  • if (strcmp(PageLog, "syslog"))
  • if (strcmp(PageLog, "syslog") && strcmp(PageLog, "journal"))
    cupsdCheckLogFile(&PageFile, PageLog);

/*
diff --git a/scheduler/conf.h b/scheduler/conf.h
index dd69bdf..b5d185a 100644
--- a/scheduler/conf.h
+++ b/scheduler/conf.h
@@ -287,16 +287,69 @@ extern int cupsdLogGSSMessage(int level, OM_uint32 major_status,
OM_uint32 minor_status,
const char message, ...);
#endif /
HAVE_GSSAPI */
-extern int cupsdLogJob(cupsd_job_t *job, int level, const char *message,

  •               ...) **attribute**((**format**(**printf**, 3, 4)));
    
    -extern int cupsdLogMessage(int level, const char *message, ...)
  •   **attribute** ((**format** (**printf**, 2, 3)));
    
    +extern int _cupsdLogJobWithLocation(const char *file,
  •                const char *line,
    
  •                const char *func,
    
  •                cupsd_job_t *job,
    
  •                int level,
    
  •                const char *message,
    
  •                ...)
    
  •   **attribute**((**format**(**printf**, 6, 7)));
    
    +extern int _cupsdLogMessageWithLocation(const char *file,
  •                    const char *line,
    
  •                    const char *func,
    
  •                    int level,
    
  •                    const char *message,
    
  •                    ...)
    
  •   **attribute** ((**format** (**printf**, 5, 6)));
    
    extern int cupsdLogPage(cupsd_job_t *job, const char *page);
    extern int cupsdLogRequest(cupsd_client_t *con, http_status_t code);
    extern int cupsdReadConfiguration(void);
    -extern int cupsdWriteErrorLog(int level, const char *message);
    +extern int _cupsdWriteErrorLogJobWithLocation(const char *file,
  •                      const char *line,
    
  •                      const char *func,
    
  •                      cupsd_job_t *job,
    
  •                      int level,
    
  •                      const char *message);
    
    +extern int _cupsdWriteErrorLogWithLocation(const char *file,
  •                   const char *line,
    
  •                   const char *func,
    
  •                   int level, const char *message);
    

+#ifndef _CUPSD_STRINGIFY
+#define _CUPSD_XSTRINGIFY(x) #x
+#define _CUPSD_STRINGIFY(x) _CUPSD_XSTRINGIFY(x)
+#endif /* !defined(_CUPSD_STRINGIFY) */
+
+#define cupsdLogJob(...) \

  • _cupsdLogJobWithLocation("CODE_FILE=" FILE, \

  •            "CODE_LINE="               \
    
  •            _CUPSD_STRINGIFY(__LINE__),        \
    
  •            **func**,              \
    
  •            **VA_ARGS**)
    

    +#define cupsdLogMessage(...) \

  • _cupsdLogMessageWithLocation("CODE_FILE=" FILE, \

  •                "CODE_LINE="           \
    
  •                _CUPSD_STRINGIFY(__LINE__),    \
    
  •                **func**,              \
    
  •                **VA_ARGS**)
    

    +#define cupsdWriteErrorLogJob(...) \

  • _cupsdWriteErrorLogJobWithLocation("CODE_FILE=" FILE, \

  •              "CODE_LINE="             \
    
  •              _CUPSD_STRINGIFY(__LINE__),      \
    
  •              **func**,                \
    
  •              **VA_ARGS**)
    

    +#define cupsdWriteErrorLog(...) \

  • _cupsdWriteErrorLogWithLocation("CODE_FILE=" FILE, \

  •           "CODE_LINE="            \
    
  •           _CUPSD_STRINGIFY(__LINE__),     \
    
  •           **func**,               \
    
  •           __VA_ARGS__)
    

    /*

    • End of "$Id$".
      /
      diff --git a/scheduler/log.c b/scheduler/log.c
      index aac4b2e..36c1ef9 100644
      --- a/scheduler/log.c
      +++ b/scheduler/log.c
      @@ -20,6 +20,12 @@
      #include "cupsd.h"
      #include <stdarg.h>
      #include <syslog.h>
      +#include <sys/uio.h>
      +#ifdef HAVE_SYSTEMD
      +/
      We handle location fields ourselves /
      +# define SD_JOURNAL_SUPPRESS_LOCATION
      +# include <systemd/sd-journal.h>
      +#endif /
      HAVE_SYSTEMD */

    /*
    @@ -480,15 +486,135 @@ cupsdLogClient(cupsd_client_t con, / I - Client connection */
    }

+#ifdef HAVE_SYSTEMD
+static int
+dup_iovec_string(struct iovec *vec,

  •    const char *str)
    
    +{
  • vec->iov_base = strdup (str);
  • vec->iov_len = strlen (str);
  • return (vec->iov_base ? 1 : 0);
    +}

+/*

  • * '_cupsdLogToJournal()' - Log to journal with fields
  • /
    +static int /
    O - 1 on success, 0 on error _/
    +cupsdLogToJournal(const char *file, / I - Code file */
  •      const char   _line,  /_ I - Code line */
    
  •      const char   _func,  /_ I - Code func */
    
  •      cupsd_job_t  _job,   /_ I - Job or NULL */
    
  •      int      level,  /\* I - Log level */
    
  •      const char   _message)/_ I - Formatted message */
    
    +{
  • size_t n_journal_fields;
  • struct iovec *journal_fields = NULL;
  • char buffer[256];
  • int result = 1;
  • /*
  • * There will be at least 5 fields:
  • * CODE_FILE, CODE_LINE, CODE_FUNC, MESSAGE, PRIORITY
  • */
  • n_journal_fields = 5;
  • if (job)
  • {
  • n_journal_fields++; /* CUPS_JOB_ID */
  • if (job->dest)
  •  n_journal_fields++; /\* CUPS_DEST */
    
  • if (job->printer)
  •  n_journal_fields++; /\* CUPS_PRINTER */
    
  • }
  • journal_fields = calloc (n_journal_fields, sizeof (struct iovec));
  • if (!journal_fields)
  • return (0);
  • n_journal_fields = 0;
  • result = dup_iovec_string (&journal_fields[n_journal_fields], file);
  • if (result)
  • {
  • n_journal_fields++;
  • result = dup_iovec_string (&journal_fields[n_journal_fields], line);
  • }
  • if (result)
  • {
  • n_journal_fields++;
  • snprintf (buffer, sizeof (buffer), "CODE_FUNC=%s", func);
  • result = dup_iovec_string (&journal_fields[n_journal_fields], buffer);
  • }
  • if (result)
  • {
  • n_journal_fields++;
  • snprintf (buffer, sizeof (buffer), "MESSAGE=%s", log_line);
  • result = dup_iovec_string (&journal_fields[n_journal_fields], buffer);
  • }
  • if (result)
  • {
  • n_journal_fields++;
  • snprintf (buffer, sizeof (buffer), "PRIORITY=%i", syslevels[level]);
  • result = dup_iovec_string (&journal_fields[n_journal_fields], buffer);
  • }
  • if (result && job)
  • {
  • n_journal_fields++;
  • snprintf (buffer, sizeof (buffer), "CUPS_JOB_ID=%d", job->id);
  • result = dup_iovec_string (&journal_fields[n_journal_fields], buffer);
  • if (result && job->dest)
  • {
  •  n_journal_fields++;
    
  •  snprintf (buffer, sizeof (buffer), "CUPS_DEST=%s", job->dest);
    
  •  result = dup_iovec_string (&journal_fields[n_journal_fields], buffer);
    
  • }
  • if (result && job->printer)
  • {
  •  n_journal_fields++;
    
  •  snprintf (buffer, sizeof (buffer), "CUPS_PRINTER=%s",
    
  •   job->printer->name);
    
  •  result = dup_iovec_string (&journal_fields[n_journal_fields], buffer);
    
  • }
  • }
  • if (result)
  • {
  • n_journal_fields++;
  • result = sd_journal_sendv (journal_fields, n_journal_fields);
  • }
  • while (n_journal_fields > 0)
  • free (journal_fields[--n_journal_fields].iov_base);
  • free (journal_fields);
  • return (result);
    +}
    +#endif /* HAVE_SYSTEMD _/

/_

  • 'cupsdLogJob()' - Log a job message.
    */

-int /* O - 1 on success, 0 on error /
-cupsdLogJob(cupsd_job_t *job, /
I - Job */

  •        int         level,     /\* I - Log level */
    
  •   const char  _message,   /_ I - Printf-style message string */
    
  •   ...)            /\* I - Additional arguments as needed _/
    
    +int /_ O - 1 on success, 0 on error _/
    +cupsdLogJobWithLocation(const char *file, / I - Code file */
  •        const char _line,  /_ I - Code line */
    
  •        const char _func,  /_ I - Code func */
    
  •        cupsd_job_t _job,  /_ I - Job */
    
  •        int         level, /\* I - Log level */
    
  •        const char  _message,  /_ I - Printf-style message string */
    
  •        ...)           /\* I - Additional arguments as needed _/
    
    {
    va_list ap, ap2; /_ Argument pointers /
    char jobmsg[1024]; /
    Format string for job message /
    @@ -574,8 +700,14 @@ cupsdLogJob(cupsd_job_t *job, /
    I - Job */
    }
    else if (level <= LogLevel &&
    (level != CUPSD_LOG_INFO || LogLevel >= CUPSD_LOG_DEBUG))
  •  return (cupsdWriteErrorLog(level, log_line));
    
  • else
  • {
    +#ifdef HAVE_SYSTEMD
  •  if (!strcmp (ErrorLog, "journal"))
    
  • return (_cupsdLogToJournal (file, line, func, job, level, log_line));
  •  else
    
    +#endif /* HAVE_SYSTEMD */
  • return (cupsdWriteErrorLog(level, log_line));
  • } else
    return (1);
    }
    else
    @@ -588,10 +720,13 @@ cupsdLogJob(cupsd_job_t job, / I - Job */
  • 'cupsdLogMessage()' - Log a message to the error log file.
    */

-int /* O - 1 on success, 0 on error /
-cupsdLogMessage(int level, /
I - Log level */

  •            const char _message,   /_ I - printf-style message string */
    
  •       ...)            /\* I - Additional args as needed _/
    

    +int /_ O - 1 on success, 0 on error _/
    +cupsdLogMessageWithLocation(const char *file, / I - Code file */

  •            const char _line,  /_ I - Code line */
    
  •            const char _func,  /_ I - Code func */
    
  •            int        level,  /\* I - Log level */
    
  •            const char _message, /_ I - printf-style message string */
    
  •            ...)       /* I - Additional args as needed */
    

    {
    va_list ap, ap2; /* Argument pointers /
    int status; /
    Formatting status /
    @@ -635,10 +770,10 @@ cupsdLogMessage(int level, /
    I - Log level */
    va_end(ap);

    if (status > 0)

  • return (cupsdWriteErrorLog(level, log_line));

  • return (_cupsdWriteErrorLogWithLocation(file, line, func, level, log_line));
    else

  • return (cupsdWriteErrorLog(CUPSD_LOG_ERROR,

  •                           "Unable to allocate memory for log line!"));
    
  • return (_cupsdWriteErrorLogWithLocation(file, line, func, CUPSD_LOG_ERROR,

  •                   "Unable to allocate memory for log line!"));
    

    }

@@ -831,6 +966,17 @@ cupsdLogPage(cupsd_job_t job, / I - Job being printed */

*bufptr = '\0';

+#ifdef HAVE_SYSTEMD

  • if (!strcmp(PageLog, "journal"))

  • return (sd_journal_send ("MESSAGE=%s", buffer,

  •            "PRIORITY=%d", LOG_INFO,
    
  •            "CUPS_JOB_ID=%d", job->id,
    
  •            "CUPS_DEST=%s", job->dest,
    
  •            "CUPS_PRINTER=%s", job->printer->name,
    
  •            "CUPS_PAGE_NUMBER=%s", number,
    
  •            NULL) ? 0 : 1);
    

    +#endif /* HAVE_SYSTEMD /
    +
    #ifdef HAVE_VSYSLOG
    /

    • See if we are logging pages via syslog...
      @@ -1008,7 +1154,7 @@ cupsdLogRequest(cupsd_client_t con, / I - Request to log */
    • See if we are logging accesses via syslog...
      */
  • if (!strcmp(AccessLog, "syslog"))

  • if (!strcmp(AccessLog, "syslog") || !strcmp(AccessLog, "journal"))
    {
    syslog(LOG_INFO,
    "REQUEST %s - %s "%s %s HTTP/%d.%d" %d " CUPS_LLFMT " %s %s\n",
    @@ -1062,8 +1208,12 @@ cupsdLogRequest(cupsd_client_t con, / I - Request to log */
    */

int /* O - 1 on success, 0 on failure /
-cupsdWriteErrorLog(int level, /
I - Log level */

  •               const char _message)    /_ I - Message string _/
    
    +cupsdWriteErrorLogJobWithLocation(const char *file, / I - Code file */
  •              const char _line,    /_ I - Code line */
    
  •              const char _func,    /_ I - Code func */
    
  •              cupsd_job_t _job,    /_ I - Job or NULL */
    
  •              int         level,   /\* I - Log level */
    
  •              const char _message) /_ I - Message string _/
    
    {
    int ret = 1; /_ Return value /
    static const char levels[] = /
    Log levels... /
    @@ -1081,6 +1231,10 @@ cupsdWriteErrorLog(int level, /
    I - Log level */
    };

+#ifdef HAVE_SYSTEMD

  • if (!strcmp(ErrorLog, "journal"))
  • return (_cupsdLogToJournal (file, line, func, job, level, message));
    +#endif /* HAVE_SYSTEMD /
    #ifdef HAVE_VSYSLOG
    /
  • See if we are logging errors via syslog...
    @@ -1121,6 +1275,22 @@ cupsdWriteErrorLog(int level, /* I - Log level */

/*

  • * 'cupsdWriteErrorLog()' - Write a line to the ErrorLog.

  • /
    +
    +int /
    O - 1 on success, 0 on failure _/
    +cupsdWriteErrorLogWithLocation(const char *file, / I - Code file */

  •           const char _line,   /_ I - Code line */
    
  •           const char _func,   /_ I - Code func */
    
  •           int          level, /\* I - Log level */
    
  •           const char  _message)   /_ I - Message string */
    

    +{

  • return (_cupsdWriteErrorLogJobWithLocation(file, line, func,

  •                    NULL, level, message));
    

    +}
    +
    +
    +/*

    • 'format_log_line()' - Format a line for a log file.
      *

    * This function resizes a global string buffer as needed. Each call returns

    2.1.0

@michaelrsweet
Copy link
Collaborator Author

"str4474.patch":

Index: config-scripts/cups-common.m4

--- config-scripts/cups-common.m4 (revision 12685)
+++ config-scripts/cups-common.m4 (working copy)
@@ -137,6 +137,8 @@
AC_CHECK_HEADER(sys/ioctl.h,AC_DEFINE(HAVE_SYS_IOCTL_H))
AC_CHECK_HEADER(sys/param.h,AC_DEFINE(HAVE_SYS_PARAM_H))
AC_CHECK_HEADER(sys/ucred.h,AC_DEFINE(HAVE_SYS_UCRED_H))
+AC_CHECK_HEADER(asl.h,AC_DEFINE(HAVE_ASL_H))
+AC_CHECK_HEADER(systemd/sd-journal.h,AC_DEFINE(HAVE_SYSTEMD_SD_JOURNAL_H))

dnl Checks for iconv.h and iconv_open
AC_CHECK_HEADER(iconv.h,

Index: config-scripts/cups-startup.m4

--- config-scripts/cups-startup.m4 (revision 12685)
+++ config-scripts/cups-startup.m4 (working copy)
@@ -56,11 +56,11 @@
AC_MSG_ERROR(Need pkg-config to enable systemd support.)
fi
else

  •       AC_MSG_CHECKING(for libsystemd-daemon)
    
  •            if $PKGCONFIG --exists libsystemd-daemon; then
    
  •       AC_MSG_CHECKING(for libsystemd)
    
  •            if $PKGCONFIG --exists libsystemd; then
                     AC_MSG_RESULT(yes)
    
  •                    ONDEMANDFLAGS=`$PKGCONFIG --cflags libsystemd-daemon`
    
  •                    ONDEMANDLIBS=`$PKGCONFIG --libs libsystemd-daemon`
    
  •                    ONDEMANDFLAGS=`$PKGCONFIG --cflags libsystemd`
    
  •                    ONDEMANDLIBS=`$PKGCONFIG --libs libsystemd`
                     AC_DEFINE(HAVE_SYSTEMD)
        if test "x$SYSTEMD_DIR" = x; then
                SYSTEMD_DIR="`$PKGCONFIG --variable=systemdsystemunitdir systemd`"
    

    Index: config.h.in

    --- config.h.in (revision 12685)
    +++ config.h.in (working copy)
    @@ -243,6 +243,20 @@

    /*

  • * Do we have the ASL functions?

  • /
    +
    +#undef HAVE_ASL_H
    +
    +
    +/

  • * Do we have the systemd journal functions?

  • /
    +
    +#undef HAVE_SYSTEMD_SD_JOURNAL_H
    +
    +
    +/

    • Do we have the (v)snprintf() functions?
      */

Index: scheduler/log.c

--- scheduler/log.c (revision 12685)
+++ scheduler/log.c (working copy)
@@ -3,7 +3,7 @@
*

  • Log file routines for the CUPS scheduler.
    *

    • * Copyright 2007-2014 by Apple Inc.
    • * Copyright 2007-2015 by Apple Inc.
  • Copyright 1997-2007 by Easy Software Products, all rights reserved.
    *

  • These coded instructions, statements, and computer programs are the
    @@ -19,10 +19,44 @@

    #include "cupsd.h"
    #include <stdarg.h>
    +#ifdef HAVE_ASL_H
    +# include <asl.h>
    +#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
    +# define SD_JOURNAL_SUPPRESS_LOCATION
    +# include <systemd/sd-journal.h>
    +#endif /* HAVE_ASL_H */
    #include <syslog.h>

    /*

    • * Constants for log keys from PWG 5110.3 (PWG Common Log Format)...
    • /
      +
      +#define PWG_DeviceUUID "DUU"
      +#define PWG_Event "E"
      +#define PWG_LogNaturalLanguage "NL"
      +#define PWG_Status "S"
      +#define PWG_ServiceURI "URI"
      +#define PWG_UserHost "UH"
      +#define PWG_UserName "UN"
      +#define PWG_UserURI "UU"
      +#define PWG_ServiceIsAcceptingJobs "IAJ"
      +#define PWG_ServiceState "ST"
      +#define PWG_ServiceStateReasons "SR"
      +#define PWG_ServiceUUID "SUU"
      +#define PWG_JobID "JID"
      +#define PWG_JobUUID "JUU"
      +#define PWG_JobImagesCompleted "JIM"
      +#define PWG_JobImpressionsCompleted "JIC"
      +#define PWG_JobDestinationURI "JD"
      +#define PWG_JobState "JS"
      +#define PWG_JobStateReasons "JR"
      +#define PWG_JobAccountingID "JA"
      +#define PWG_JobAcountingUserName "JAUN"
      +#define PWG_JobAccountingUserURI "JAUU"
      +
      +
      +/
  • Local globals...
    */

@@ -31,9 +65,23 @@
static size_t log_linesize = 0; /* Size of line for output file /
static char *log_line = NULL; /
Line for output file */

-#ifdef HAVE_VSYSLOG
-static const int syslevels[] = /* SYSLOG levels... /
+#ifdef HAVE_ASL_H
+static const int log_levels[] = /
ASL levels... */
{

  •     ASL_LEVEL_EMERG,
    
  •     ASL_LEVEL_EMERG,
    
  •     ASL_LEVEL_ALERT,
    
  •     ASL_LEVEL_CRIT,
    
  •     ASL_LEVEL_ERR,
    
  •     ASL_LEVEL_WARNING,
    
  •     ASL_LEVEL_NOTICE,
    
  •     ASL_LEVEL_INFO,
    
  •     ASL_LEVEL_DEBUG,
    
  •     ASL_LEVEL_DEBUG
    
  •   };
    

    +#elif defined(HAVE_VSYSLOG) || defined(HAVE_SYSTEMD_SD_JOURNAL_H)
    +static const int log_levels[] = /* SYSLOG levels... */

  •   {
      0,
      LOG_EMERG,
      LOG_ALERT,
    

    @@ -45,7 +93,7 @@
    LOG_DEBUG,
    LOG_DEBUG
    };
    -#endif /* HAVE_VSYSLOG /
    +#endif /
    HAVE_ASL_H */

    /*
    @@ -169,9 +217,21 @@

    if (*lf == NULL)
    {

  • syslog(LOG_ERR, "Unable to open log file "%s" - %s", filename,

  •      strerror(errno));
    

    +#ifdef HAVE_ASL_H

  • asl_object_t m; /* Log message */

  • m = asl_new(ASL_TYPE_MSG);

  • asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");

  • asl_log(NULL, m, ASL_LEVEL_ERR, "Unable to open log file "%s" - %s", filename, strerror(errno));

  • asl_release(m);

+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)

  •    sd_journal_print(LOG_ERR, "Unable to open log file \"%s\" - %s", filename, strerror(errno));
    
    +#else
  • syslog(LOG_ERR, "Unable to open log file "%s" - %s", filename, strerror(errno));
    +#endif /* HAVE_ASL_H */
  • if (FatalErrors & CUPSD_FATAL_LOG)
    cupsdEndProcess(getpid(), 0);

@@ -211,9 +271,21 @@

 if ((*lf = cupsFileOpen(filename, "a")) == NULL)
 {
  •  syslog(LOG_ERR, "Unable to open log file \"%s\" - %s", filename,
    
  •         strerror(errno));
    
    +#ifdef HAVE_ASL_H
  • asl_object_t m; /* Log message */
  • m = asl_new(ASL_TYPE_MSG);
  • asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
  • asl_log(NULL, m, ASL_LEVEL_ERR, "Unable to open log file "%s" - %s", filename, strerror(errno));
  • asl_release(m);

+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)

  •    sd_journal_print(LOG_ERR, "Unable to open log file \"%s\" - %s", filename, strerror(errno));
    
    +#else
  • syslog(LOG_ERR, "Unable to open log file "%s" - %s", filename, strerror(errno));
    +#endif /* HAVE_ASL_H */
  • if (FatalErrors & CUPSD_FATAL_LOG)
    cupsdEndProcess(getpid(), 0);

@@ -507,6 +579,86 @@
LogDebugHistory <= 0)
return (1);

+#ifdef HAVE_ASL_H

  • if (!strcmp(ErrorLog, "syslog"))
  • {
  • asl_object_t m; /* Log message */
  • char job_id[32], /* job-id string */
  •       completed[32];  /\* job-impressions-completed string */
    
  • static const char * const job_states[] =
  • { /* job-state strings */
  •  "Pending",
    
  •  "PendingHeld",
    
  •  "Processing",
    
  •  "ProcessingStopped",
    
  •  "Canceled",
    
  •  "Aborted",
    
  •  "Completed"
    
  • };
  • snprintf(job_id, sizeof(job_id), "%d", job->id);
  • m = asl_new(ASL_TYPE_MSG);
  • asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
  • asl_set(m, PWG_Event, "JobStateChanged");
  • asl_set(m, PWG_ServiceURI, job->printer->uri);
  • asl_set(m, PWG_JobID, job_id);
  • asl_set(m, PWG_JobState, job_states[job->state_value - IPP_JSTATE_PENDING]);
  • if (job->impressions)
  • {
  •  snprintf(completed, sizeof(completed), "%d", ippGetInteger(job->impressions, 0));
    
  •  asl_set(m, PWG_JobImpressionsCompleted, completed);
    
  • }
  • va_start(ap, message);
  • asl_vlog(NULL, m, log_levels[level], message, ap);
  • va_end(ap);
  • asl_release(m);
  • return (1);
  • }

+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)

  • if (!strcmp(ErrorLog, "syslog"))
  • {
  • char completed[32]; /* job-impressions-completed string */
  • static const char * const job_states[] =
  • { /* job-state strings */
  •  "Pending",
    
  •  "PendingHeld",
    
  •  "Processing",
    
  •  "ProcessingStopped",
    
  •  "Canceled",
    
  •  "Aborted",
    
  •  "Completed"
    
  • };
  • va_start(ap, message);
  • do
  • {
  •  va_copy(ap2, ap);
    
  •  status = format_log_line(message, ap2);
    
  •  va_end(ap2);
    
  • }
  • while (status == 0);
  • va_end(ap);
  • sd_journal_send("MESSAGE=%s", log_line,
  •                "PRIORITY=%i", log_levels[level],
    
  •       PWG_Event"=JobStateChanged",
    
  •       PWG_ServiceURI"=%s", job->printer->uri,
    
  •       PWG_JobID"=%d", job->id,
    
  •       PWG_JobState"=%s", job_states[job->state_value - IPP_JSTATE_PENDING],
    
  •       PWG_JobImpressionsCompleted"=%d", ippGetInteger(job->impressions, 0),
    
  •       NULL);
    
  • return (1);
  • }

+#endif /* HAVE_ASL_H /
+
/

  • Format and write the log message...
    */
    @@ -604,12 +756,26 @@
    if ((TestConfigFile || !ErrorLog) && level <= CUPSD_LOG_WARN)
    {
    va_start(ap, message);
    -#ifdef HAVE_VSYSLOG
  • vsyslog(LOG_LPR | syslevels[level], message, ap);

+#ifdef HAVE_ASL_H

  • asl_object_t m; /* Log message */
  • m = asl_new(ASL_TYPE_MSG);
  • asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
  • asl_vlog(NULL, m, log_levels[level], message, ap);
  • asl_release(m);

+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)

  • sd_journal_printv(log_levels[level], message, ap);

+#elif defined(HAVE_VSYSLOG)

  • vsyslog(LOG_LPR | log_levels[level], message, ap);

#else
vfprintf(stderr, message, ap);
putc('\n', stderr);
#endif /* HAVE_VSYSLOG */
+
va_end(ap);

return (1);
@@ -618,6 +784,27 @@
if (level > LogLevel || !ErrorLog)
return (1);

+#ifdef HAVE_ASL_H

  • if (!strcmp(ErrorLog, "syslog"))
  • {
  • asl_object_t m; /* Log message */
  • m = asl_new(ASL_TYPE_MSG);
  • asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
  • va_start(ap, message);
  • asl_vlog(NULL, m, log_levels[level], message, ap);
  • va_end(ap);
  • asl_release(m);
  • return (1);
  • }

+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)

  • sd_journal_printv(log_levels[level], message, ap);

+#endif /* HAVE_ASL_H /
+
/

  • Format and write the log message...
    */
    @@ -831,7 +1018,83 @@

*bufptr = '\0';

-#ifdef HAVE_VSYSLOG
+#ifdef HAVE_ASL_H

  • if (!strcmp(ErrorLog, "syslog"))
  • {
  • asl_object_t m; /* Log message */
  • char job_id[32], /* job-id string */
  •       completed[32];  /\* job-impressions-completed string */
    
  • static const char * const job_states[] =
  • { /* job-state strings */
  •  "Pending",
    
  •  "PendingHeld",
    
  •  "Processing",
    
  •  "ProcessingStopped",
    
  •  "Canceled",
    
  •  "Aborted",
    
  •  "Completed"
    
  • };
  • snprintf(job_id, sizeof(job_id), "%d", job->id);
  • m = asl_new(ASL_TYPE_MSG);
  • asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
  • asl_set(m, PWG_Event, "JobStateChanged");
  • asl_set(m, PWG_ServiceURI, job->printer->uri);
  • asl_set(m, PWG_JobID, job_id);
  • asl_set(m, PWG_JobState, job_states[job->state_value - IPP_JSTATE_PENDING]);
  • if (job->impressions)
  • {
  •  snprintf(completed, sizeof(completed), "%d", ippGetInteger(job->impressions, 0));
    
  •  asl_set(m, PWG_JobImpressionsCompleted, completed);
    
  • }
  • asl_log(NULL, m, ASL_LEVEL_INFO, "%s", buffer);
  • asl_release(m);
  • return (1);
  • }

+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)

  • if (!strcmp(ErrorLog, "syslog"))
  • {
  • char completed[32]; /* job-impressions-completed string */
  • static const char * const job_states[] =
  • { /* job-state strings */
  •  "Pending",
    
  •  "PendingHeld",
    
  •  "Processing",
    
  •  "ProcessingStopped",
    
  •  "Canceled",
    
  •  "Aborted",
    
  •  "Completed"
    
  • };
  • va_start(ap, message);
  • do
  • {
  •  va_copy(ap2, ap);
    
  •  status = format_log_line(message, ap2);
    
  •  va_end(ap2);
    
  • }
  • while (status == 0);
  • va_end(ap);
  • sd_journal_send("MESSAGE=%s", log_line,
  •                "PRIORITY=%i", log_levels[level],
    
  •       PWG_Event"=JobStateChanged",
    
  •       PWG_ServiceURI"=%s", job->printer->uri,
    
  •       PWG_JobID"=%d", job->id,
    
  •       PWG_JobState"=%s", job_states[job->state_value - IPP_JSTATE_PENDING],
    
  •       PWG_JobImpressionsCompleted"=%d", ippGetInteger(job->impressions, 0),
    
  •       NULL);
    
  • return (1);
  • }

+#elif defined(HAVE_VSYSLOG)
/*

  • See if we are logging pages via syslog...
    */
    @@ -842,7 +1105,7 @@

    return (1);
    }
    -#endif /* HAVE_VSYSLOG /
    +#endif /
    HAVE_ASL_H */

/*

  • Not using syslog; check the log file...
    @@ -1003,7 +1266,32 @@
    }
    }

-#ifdef HAVE_VSYSLOG
+#ifdef HAVE_ASL_H

  • if (!strcmp(ErrorLog, "syslog"))
  • {
  • asl_object_t m; /* Log message */
  • m = asl_new(ASL_TYPE_MSG);
  • asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
  • asl_log(NULL, m, ASL_LEVEL_INFO, "REQUEST %s - %s "%s %s HTTP/%d.%d" %d " CUPS_LLFMT " %s %s\n",
  •       con->http->hostname, con->username[0] != '\0' ? con->username : "-",
    
  •  states[con->operation], _httpEncodeURI(temp, con->uri, sizeof(temp)),
    
  •  con->http->version / 100, con->http->version % 100,
    
  •  code, CUPS_LLCAST con->bytes,
    
  •  con->request ?
    
  •      ippOpString(con->request->request.op.operation_id) : "-",
    
  •  con->response ?
    
  •      ippErrorString(con->response->request.status.status_code) : "-");
    
  • asl_release(m);
  • return (1);
  • }

+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)

  • sd_journal_print(LOG_INFO, "REQUEST %s - %s "%s %s HTTP/%d.%d" %d " CUPS_LLFMT " %s %s", con->http->hostname, con->username[0] != '\0' ? con->username : "-", states[con->operation], _httpEncodeURI(temp, con->uri, sizeof(temp)), con->http->version / 100, con->http->version % 100, code, CUPS_LLCAST con->bytes, con->request ? ippOpString(con->request->request.op.operation_id) : "-", con->response ? ippErrorString(con->response->request.status.status_code) : "-");

+#elif defined(HAVE_VSYSLOG)
/*

  • See if we are logging accesses via syslog...
    */
    @@ -1023,7 +1311,7 @@

    return (1);
    }
    -#endif /* HAVE_VSYSLOG /
    +#endif /
    HAVE_ASL_H */

/*

  • Not using syslog; check the log file...
    @@ -1081,17 +1369,33 @@
    };

-#ifdef HAVE_VSYSLOG
+#ifdef HAVE_ASL_H

  • if (!strcmp(ErrorLog, "syslog"))
  • {
  • asl_object_t m; /* Log message */
  • m = asl_new(ASL_TYPE_MSG);
  • asl_set(m, ASL_KEY_FACILITY, "org.cups.cupsd");
  • asl_log(NULL, m, ASL_LEVEL_INFO, "%s", message);
  • asl_release(m);
  • return (1);
  • }

+#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)

  • sd_journal_print(log_levels[level], "%s", message);

+#elif defined(HAVE_VSYSLOG)
/*

  • See if we are logging errors via syslog...
    */

if (!strcmp(ErrorLog, "syslog"))
{

  • syslog(syslevels[level], "%s", message);
  • syslog(log_levels[level], "%s", message);
    return (1);
    }
    -#endif /* HAVE_VSYSLOG /
    +#endif /
    HAVE_ASL_H */

/*

  • Not using syslog; check the log file...
    Index: xcode/config.h

    --- xcode/config.h (revision 12685)
    +++ xcode/config.h (working copy)
    @@ -248,6 +248,20 @@

/*

  • * Do we have the ASL functions?
  • /
    +
    +#define HAVE_ASL_H
    +
    +
    +/
  • * Do we have the systemd journal functions?
  • /
    +
    +/
    #undef HAVE_SYSTEMD_SD_JOURNAL_H_/
    +
    +
    +/_
    • Do we have the (v)snprintf() functions?
      */

@michaelrsweet
Copy link
Collaborator Author

"0001-Fix-crash-when-logging-via-journald.patch":

From 667091959e964bb6a1a7e4e8a6cc29b0dfd726b2 Mon Sep 17 00:00:00 2001
From: Jiri Popelka jpopelka@redhat.com
Date: Mon, 29 Jun 2015 16:27:40 +0200
Subject: [PATCH] Fix crash when logging via journald.

Signed-off-by: Jiri Popelka jpopelka@redhat.com

scheduler/log.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/scheduler/log.c b/scheduler/log.c
index cd4e362..b7dff70 100644
--- a/scheduler/log.c
+++ b/scheduler/log.c
@@ -812,7 +812,9 @@ cupsdLogMessage(int level, /* I - Log level */
#elif defined(HAVE_SYSTEMD_SD_JOURNAL_H)
if (!strcmp(ErrorLog, "syslog"))
{

  • va_start(ap, message);
    sd_journal_printv(log_levels[level], message, ap);
  • va_end(ap);
    return (1);
    }
    #endif /* HAVE_ASL_H */
    --
    2.4.3

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: jpopelka

Trying 2.1b1 results in crash, patch attached.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Please file a new bug (this one is closed)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant