]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Add support for ASL and journald when doing "syslog" logging (STR #4474)
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Wed, 3 Jun 2015 17:19:04 +0000 (17:19 +0000)
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Wed, 3 Jun 2015 17:19:04 +0000 (17:19 +0000)
git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@12687 a1ca3aef-8c08-0410-bb20-df032aa958be

CHANGES.txt
config-scripts/cups-common.m4
config-scripts/cups-startup.m4
config.h.in
scheduler/log.c
xcode/config.h

index ca16db13150575e77f4718dff65c5bea5ee687ec..f4f6c4aa6c8c3b57c97ca83c71e66d93e16ab5c0 100644 (file)
@@ -1,4 +1,4 @@
-CHANGES.txt - 2.1b1 - 2015-05-25
+CHANGES.txt - 2.1b1 - 2015-06-03
 --------------------------------
 
 CHANGES IN CUPS V2.1b1
@@ -35,3 +35,5 @@ CHANGES IN CUPS V2.1b1
          disable TLS/1.0 support.
        - Updated the scheduler to support more IPP Everywhere attributes
          (STR #4630)
+       - The scheduler now supports advanced ASL and journald logging when
+         "syslog" output is configured (STR #4474)
index 3730f6dd4096719f1ec2544ff97efa63cca0f1e3..62190b876a02da096f0822cd4e4758b1abe0ff8d 100644 (file)
@@ -137,6 +137,8 @@ AC_CHECK_HEADER(bstring.h,AC_DEFINE(HAVE_BSTRING_H))
 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 e98009e6e962be44cb51f081178ed2b4b2cea440..e6aaf6a4042aa9f942b184013ed615bb2c87fa22 100644 (file)
@@ -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`"
index 098574913e3f8b1651edb2d38ab2995eaf5283cc..9a4ed16cdcb748c837f0f1ed8e39b3e1ac3d9350 100644 (file)
 #undef HAVE_VSYSLOG
 
 
+/*
+ * 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 aac4b2e2f89481cfee07a1e93f1daec096323afe..5ade44aa3159eb021f0cdcd8d6bf72585a4d80a7 100644 (file)
@@ -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
 
 #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,8 +65,22 @@ static _cups_mutex_t log_mutex = _CUPS_MUTEX_INITIALIZER;
 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,
@@ -45,7 +93,7 @@ static const int syslevels[] =                /* SYSLOG levels... */
                  LOG_DEBUG,
                  LOG_DEBUG
                };
-#endif /* HAVE_VSYSLOG */
+#endif /* HAVE_ASL_H */
 
 
 /*
@@ -169,8 +217,20 @@ cupsdCheckLogFile(cups_file_t **lf,        /* IO - Log file */
 
       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,8 +271,20 @@ cupsdCheckLogFile(cups_file_t **lf,        /* IO - Log file */
 
     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 @@ cupsdLogJob(cupsd_job_t *job,              /* I - Job */
       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 @@ cupsdLogMessage(int        level, /* I - Log level */
   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 @@ cupsdLogMessage(int        level,  /* I - Log level */
   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 @@ cupsdLogPage(cupsd_job_t *job,            /* I - Job being printed */
 
   *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 @@ cupsdLogPage(cupsd_job_t *job,             /* I - Job being printed */
 
     return (1);
   }
-#endif /* HAVE_VSYSLOG */
+#endif /* HAVE_ASL_H */
 
  /*
   * Not using syslog; check the log file...
@@ -1003,7 +1266,32 @@ cupsdLogRequest(cupsd_client_t *con,     /* I - Request to log */
     }
   }
 
-#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 @@ cupsdLogRequest(cupsd_client_t *con,      /* I - Request to log */
 
     return (1);
   }
-#endif /* HAVE_VSYSLOG */
+#endif /* HAVE_ASL_H */
 
  /*
   * Not using syslog; check the log file...
@@ -1081,17 +1369,33 @@ cupsdWriteErrorLog(int        level,    /* I - Log level */
                };
 
 
-#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 0044da6b23fc1550110bbf43f49465856c181b9f..f0e03173910c0b2f50c2f93a6bcfd34c7a3ab6c7 100644 (file)
 #define HAVE_VSYSLOG 1
 
 
+/*
+ * 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?
  */