Hi,

attached patch adds new module called mod_systemd. Systemd [1] is service 
manager for Linux. Although httpd works with systemd normally, systemd provides 
sd_notify(...) function [2] to inform service manager about current status of 
the service. Status message passed to service manager using this function is 
later visible in "systemctl status httpd.service" output and can provide useful 
information about current httpd status.

The goal of this module is to update httpd's status message regularly to 
provide information like number of idle/busy workers, total requests or for 
example number of requests per second. It uses data from the ap_get_sload(...) 
function and depends on my httpd-sload.patch from previous mail.

I've tried to choose some interesting data for the status message, but if you 
think admins would like to see something different there, I'm open to 
suggestions. Note that it has to be single line of text, so there's no space 
for lot of data.

[1] http://www.freedesktop.org/wiki/Software/systemd
[2] http://www.freedesktop.org/software/systemd/man/sd_notify.html

Thanks for reviewing,
Jan Kaluza
Index: modules/arch/unix/config5.m4
===================================================================
--- modules/arch/unix/config5.m4	(revision 1389886)
+++ modules/arch/unix/config5.m4	(working copy)
@@ -19,6 +19,19 @@
   fi
 ])
 
+
+APACHE_MODULE(systemd, Systemd support, , , $unixd_mods_enabled, [
+  AC_CHECK_LIB(systemd-daemon, sd_notify, SYSTEMD_LIBS="-lsystemd-daemon")
+  AC_CHECK_HEADERS(systemd/sd-daemon.h, [ap_HAVE_SD_DAEMON_H="yes"], [ap_HAVE_SD_DAEMON_H="no"])
+  if test $ap_HAVE_SD_DAEMON_H = "no" || test -z "${SYSTEMD_LIBS}"; then
+    AC_MSG_WARN([Your system does not support systemd.])
+    enable_systemd="no"
+  else
+    APR_ADDTO(MOD_SYSTEMD_LDADD, [$SYSTEMD_LIBS])
+    enable_systemd="yes"
+  fi
+])
+
 APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
 
 APACHE_MODPATH_FINISH
Index: modules/arch/unix/mod_systemd.c
===================================================================
--- modules/arch/unix/mod_systemd.c	(revision 0)
+++ modules/arch/unix/mod_systemd.c	(working copy)
@@ -0,0 +1,103 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+
+#include <stdint.h>
+#include <ap_config.h>
+#include "ap_mpm.h"
+#include <http_core.h>
+#include <httpd.h>
+#include <http_log.h>
+#include <apr_version.h>
+#include <apr_pools.h>
+#include <apr_strings.h>
+#include "unixd.h"
+#include "scoreboard.h"
+#include "mpm_common.h"
+
+#include "systemd/sd-daemon.h"
+
+#if APR_HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+static int systemd_pre_mpm(apr_pool_t *p, ap_scoreboard_e sb_type)
+{
+    int rv;
+    pid_t pid;
+    pid = getpid();
+
+    ap_extended_status = 1;
+
+    rv = sd_notifyf(0, "READY=1\n"
+                    "STATUS=Processing requests...\n"
+                    "MAINPID=%lu",
+                    (unsigned long) pid);
+    if (rv < 0) {
+        ap_log_perror(APLOG_MARK, APLOG_ERR, 0, p, APLOGNO(00000)
+                     "sd_notifyf returned an error %d", rv);
+    }
+
+    return OK;
+}
+
+static int systemd_monitor(apr_pool_t *p, server_rec *s)
+{
+    ap_sload_t sload;
+    apr_interval_time_t up_time;
+    char bps[5];
+    int rv;
+
+    ap_get_sload(&sload);
+    /* up_time in seconds */
+    up_time = (apr_uint32_t) apr_time_sec(apr_time_now() -
+                               ap_scoreboard_image->global->restart_time);
+
+    apr_strfsize((unsigned long)((float) (sload.bytes_served)
+                                 / (float) up_time), bps);
+
+    rv = sd_notifyf(0, "READY=1\n"
+                    "STATUS=Total requests: %lu; Idle/Busy workers %d/%d;"
+                    "Requests/sec: %.3g; Bytes served/sec: %sB/sec\n",
+                    sload.access_count, sload.idle, sload.busy,
+                    ((float) sload.access_count) / (float) up_time, bps);
+
+    if (rv < 0) {
+        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00001)
+                     "sd_notifyf returned an error %d", rv);
+    }
+
+    return DECLINED;
+}
+
+static void systemd_register_hooks(apr_pool_t *p)
+{
+    /* We know the PID in this hook ... */
+    ap_hook_pre_mpm(systemd_pre_mpm, NULL, NULL, APR_HOOK_LAST);
+    /* Used to update httpd's status line using sd_notifyf */
+    ap_hook_monitor(systemd_monitor, NULL, NULL, APR_HOOK_MIDDLE);
+}
+
+module AP_MODULE_DECLARE_DATA systemd_module =
+{
+    STANDARD20_MODULE_STUFF,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    systemd_register_hooks,
+};

Reply via email to