ソースを参照

Add uptime information to server status (Step 21/?) (See #243)

bel2125 8 年 前
コミット
7d202fb2fe
1 ファイル変更89 行追加6 行削除
  1. 89 6
      src/civetweb.c

+ 89 - 6
src/civetweb.c

@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017 the Civetweb developers
+/* Copyright (c) 2013-2017 the Civetweb developers
  * Copyright (c) 2004-2013 Sergey Lyubka
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -128,9 +128,13 @@ mg_static_assert(sizeof(void *) >= sizeof(int), "data type size check");
 #define IGNORE_UNUSED_RESULT(a) ((void)((a) && 1))
 #endif
 
+
 #if defined(__GNUC__) || defined(__MINGW32__)
-#define FUNCTION_MAY_BE_UNUSED __attribute__((unused))
+
 #pragma GCC diagnostic ignored "-Wused-but-marked-unused"
+
+#define FUNCTION_MAY_BE_UNUSED __attribute__((unused))
+
 #else
 #define FUNCTION_MAY_BE_UNUSED
 #endif
@@ -399,6 +403,13 @@ typedef DWORD clockid_t;
 #ifndef CLOCK_REALTIME
 #define CLOCK_REALTIME (2)
 #endif
+#ifndef CLOCK_THREAD
+#define CLOCK_THREAD (3)
+#endif
+#ifndef CLOCK_PROCESS
+#define CLOCK_PROCESS (4)
+#endif
+
 
 #if defined(_MSC_VER) && (_MSC_VER >= 1900)
 #define _TIMESPEC_DEFINED
@@ -420,7 +431,7 @@ static int
 clock_gettime(clockid_t clk_id, struct timespec *tp)
 {
 	FILETIME ft;
-	ULARGE_INTEGER li;
+	ULARGE_INTEGER li, li2;
 	BOOL ok = FALSE;
 	double d;
 	static double perfcnt_per_sec = 0.0;
@@ -448,10 +459,41 @@ clock_gettime(clockid_t clk_id, struct timespec *tp)
 				tp->tv_nsec = (long)(d * 1.0E9);
 				ok = TRUE;
 			}
+		} else if (clk_if == CLOCK_THREAD) {
+			FILETIME t_create, t_exit, t_kernel, t_user;
+			if (GetThreadTimes(GetCurrentThread()),
+			    &t_create,
+			    &t_exit,
+			    &t_kernel,
+			    &t_user))
+				{
+					li.LowPart = t_user.dwLowDateTime;
+					li.HighPart = t_user.dwHighDateTime;
+					li2.LowPart = t_kernel.dwLowDateTime;
+					li2.HighPart = t_kernel.dwHighDateTime;
+					li.QuadPart += li2.QuadPart;
+					tp->tv_sec = (time_t)(li.QuadPart / 10000000);
+					tp->tv_nsec = (long)(li.QuadPart % 10000000) * 100;
+					ok = TRUE;
+				}
+		}
+	} else if (clk_if == CLOCK_PROCESS) {
+		FILETIME t_create, t_exit, t_kernel, t_user;
+		if (GetProcessTimes(
+		        GetCurrentProcess(), &t_create, &t_exit, &t_kernel, &t_user)) {
+			li.LowPart = t_user.dwLowDateTime;
+			li.HighPart = t_user.dwHighDateTime;
+			li2.LowPart = t_kernel.dwLowDateTime;
+			li2.HighPart = t_kernel.dwHighDateTime;
+			li.QuadPart += li2.QuadPart;
+			tp->tv_sec = (time_t)(li.QuadPart / 10000000);
+			tp->tv_nsec = (long)(li.QuadPart % 10000000) * 100;
+			ok = TRUE;
 		}
 	}
+}
 
-	return ok ? 0 : -1;
+return ok ? 0 : -1;
 }
 #endif
 
@@ -2163,8 +2205,10 @@ struct mg_context {
 	struct mg_connection *worker_connections; /* The connection struct, pre-
 	                                           * allocated for each worker */
 
-	time_t start_time;        /* Server start time, used for authentication */
-	uint64_t auth_nonce_mask; /* Mask for all nonce values */
+	time_t start_time; /* Server start time, used for authentication
+	                    * and for diagnstics. */
+
+	uint64_t auth_nonce_mask;    /* Mask for all nonce values */
 	pthread_mutex_t nonce_mutex; /* Protects nonce_count */
 	unsigned long nonce_count;   /* Used nonces, used for authentication */
 
@@ -16762,6 +16806,45 @@ mg_get_context_info_impl(const struct mg_context *ctx, char *buffer, int buflen)
 		}
 	}
 
+	/* Execution time information */
+	if (ctx) {
+		char time_str[128] = {0};
+		struct timespec tscpuusage;
+		double cpuusage = 0.0;
+		time_t start_time = ctx->start_time;
+
+		gmt_time_string(time_str, sizeof(time_str) - 1, &start_time);
+
+		if (0 == clock_gettime(CLOCK_PROCESS, &tscpuusage)) {
+			cpuusage =
+			    (double)tscpuusage.tv_sec + 1.0E-9 * (double)tscpuusage.tv_nsec;
+		}
+
+		mg_snprintf(NULL,
+		            NULL,
+		            block,
+		            sizeof(block),
+		            "\"time\" : {%s"
+		            "\"uptime\" : %.0f,%s"
+		            "\"start\" : \"%s\",%s"
+		            "\"cpuusage\" : %f%s"
+		            "}%s",
+		            eol,
+		            difftime(time(NULL), start_time),
+		            eol,
+		            time_str,
+		            eol,
+		            cpuusage,
+		            eol,
+		            eol);
+
+		context_info_length += (int)strlen(block);
+		if (context_info_length + reserved_len < buflen) {
+			strcat(buffer, block);
+		}
+	}
+
+	/* Terminate string */
 	if ((buflen > 0) && buffer && buffer[0]) {
 		if (context_info_length < buflen) {
 			strcat(buffer, eoobj);