Browse Source

Prepare data for server status (Step 8/?) (See #243)

bel2125 8 years ago
parent
commit
26ffe52fb0
3 changed files with 153 additions and 26 deletions
  1. 19 2
      include/civetweb.h
  2. 128 21
      src/civetweb.c
  3. 6 3
      src/main.c

+ 19 - 2
include/civetweb.h

@@ -1148,7 +1148,7 @@ CIVETWEB_API int mg_get_response(struct mg_connection *conn,
 CIVETWEB_API unsigned mg_check_feature(unsigned feature);
 
 
-/* Get information on the system. Useful, if in support requests.
+/* Get information on the system. Useful for support requests.
    Parameters:
      buffer: Store system information as string here.
      buflen: Length of buffer (including a byte required for a terminating 0).
@@ -1157,11 +1157,28 @@ CIVETWEB_API unsigned mg_check_feature(unsigned feature);
      The information is complete, if the return value is smaller than buflen.
    Note:
      It is possible to determine the required buflen, by first calling this
-     function with  buffer = NULL and buflen = NULL. The required buflen is
+     function with buffer = NULL and buflen = NULL. The required buflen is
      one byte more than the returned value.
 */
 CIVETWEB_API int mg_get_system_info(char *buffer, int buflen);
 
+
+/* Get context information. Useful for server diagnosis.
+   Parameters:
+     ctx: Context handle
+     buffer: Store context information here.
+     buflen: Length of buffer (including a byte required for a terminating 0).
+   Return:
+     Available size of system information, exluding a terminating 0.
+     The information is complete, if the return value is smaller than buflen.
+   Note:
+     It is possible to determine the required buflen, by first calling this
+     function with buffer = NULL and buflen = NULL. The required buflen is
+     one byte more than the returned value.
+*/
+CIVETWEB_API int
+mg_get_context_info(const struct mg_context *ctx, char *buffer, int buflen);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */

+ 128 - 21
src/civetweb.c

@@ -928,7 +928,7 @@ mg_malloc_ex(size_t size,
 
 		mg_atomic_inc(&mstat->blockCount);
 		((uintptr_t *)data)[0] = size;
-        ((uintptr_t *)data)[1] = (uintptr_t)mstat;
+		((uintptr_t *)data)[1] = (uintptr_t)mstat;
 		memory = (void *)(((char *)data) + 2 * sizeof(uintptr_t));
 	}
 
@@ -14319,8 +14319,8 @@ process_new_connection(struct mg_connection *conn)
 		int reqerr, uri_type;
 
 #if defined(USE_SERVER_STATS)
-		int mcon = mg_atomic_inc(&(conn->ctx->total_connections));
-		mg_atomic_inc(&(conn->ctx->active_connections));
+		int mcon = mg_atomic_inc(&(conn->ctx->active_connections));
+		mg_atomic_inc(&(conn->ctx->total_connections));
 		if (mcon > (conn->ctx->max_connections)) {
 			/* could use atomic compare exchange, but this
 			 * seems overkill for statistics data */
@@ -15854,7 +15854,6 @@ mg_get_system_info_impl(char *buffer, int buflen)
 #endif
 	}
 
-
 	/* Determine 32/64 bit data mode.
 	 * see https://en.wikipedia.org/wiki/64-bit_computing */
 	{
@@ -15887,6 +15886,116 @@ mg_get_system_info_impl(char *buffer, int buflen)
 }
 
 
+/* Get context information. It can be printed or stored by the caller.
+ * Return the size of available information. */
+static int
+mg_get_context_info_impl(const struct mg_context *ctx, char *buffer, int buflen)
+
+{
+	char block[256];
+	int context_info_length = 0;
+
+#if defined(_WIN32)
+	const char *eol = "\r\n";
+#else
+	const char *eol = "\n";
+#endif
+	struct mg_memory_stat *ms = get_memory_stat(ctx);
+
+	if ((buffer == NULL) || (buflen < 10)) {
+		buflen = 0;
+	}
+
+	mg_snprintf(NULL, NULL, block, sizeof(block), "{%s", eol);
+	context_info_length += (int)strlen(block);
+	if (context_info_length < buflen) {
+		strcat(buffer, block);
+	}
+
+	/* Memory information */
+	if (ms) {
+		mg_snprintf(NULL,
+		            NULL,
+		            block,
+		            sizeof(block),
+		            "\"memory\" : {%s"
+		            "\"blocks\" : %i%s"
+		            "\"used\" : %i%s"
+		            "\"maxUsed\" : %i%s"
+		            "},%s",
+		            eol,
+		            ms->blockCount,
+		            eol,
+		            ms->totalMemUsed,
+		            eol,
+		            ms->maxMemUsed,
+		            eol,
+		            eol);
+
+		context_info_length += (int)strlen(block);
+		if (context_info_length < buflen) {
+			strcat(buffer, block);
+		}
+	}
+
+
+	/* Connections information */
+	if (ctx) {
+		mg_snprintf(NULL,
+		            NULL,
+		            block,
+		            sizeof(block),
+		            "\"connections\" : {%s"
+		            "\"active\" : %i%s"
+		            "\"maxActive\" : %i%s"
+		            "\"total\" : %i%s"
+		            "},%s",
+		            eol,
+		            ctx->active_connections,
+		            eol,
+		            ctx->max_connections,
+		            eol,
+		            ctx->total_connections,
+		            eol,
+		            eol);
+
+		context_info_length += (int)strlen(block);
+		if (context_info_length < buflen) {
+			strcat(buffer, block);
+		}
+	}
+
+	/* Requests information */
+	if (ctx) {
+		mg_snprintf(NULL,
+		            NULL,
+		            block,
+		            sizeof(block),
+		            "\"requests\" : {%s"
+		            "\"total\" : %i%s"
+		            "},%s",
+		            eol,
+		            ctx->total_requests,
+		            eol,
+		            eol);
+
+		context_info_length += (int)strlen(block);
+		if (context_info_length < buflen) {
+			strcat(buffer, block);
+		}
+	}
+
+	if ((buflen > 0) && buffer && buffer[0]) {
+		char *p = strrchr(buffer, ',');
+		if (p) {
+			*p = '}';
+		}
+	}
+
+	return context_info_length;
+}
+
+
 /* Get system information. It can be printed or stored by the caller.
  * Return the size of available information. */
 int
@@ -15902,6 +16011,21 @@ mg_get_system_info(char *buffer, int buflen)
 }
 
 
+/* Get context information. It can be printed or stored by the caller.
+ * Return the size of available information. */
+int
+mg_get_context_info(const struct mg_context *ctx, char *buffer, int buflen)
+{
+	if ((buffer == NULL) || (buflen < 1)) {
+		return mg_get_context_info_impl(ctx, NULL, 0);
+	} else {
+		/* Reset buffer, so we can always use strcat. */
+		buffer[0] = 0;
+		return mg_get_context_info_impl(ctx, buffer, buflen);
+	}
+}
+
+
 /* mg_init_library counter */
 static int mg_init_library_called = 0;
 
@@ -15976,20 +16100,3 @@ mg_exit_library(void)
 
 
 /* End of civetweb.c */
-
-#if 0
-// Just for test - TODO: add some interface
-void
-printctxinfo(struct mg_context *ctx)
-{
-	struct mg_memory_stat *ms = get_memory_stat(ctx);
-	printf("%10i %10i %10i | %10i %10i %10i | %10i\n",
-	       ms->blockCount,
-	       ms->totalMemUsed,
-	       ms->maxMemUsed,
-	       ctx->active_connections,
-	       ctx->total_connections,
-	       ctx->max_connections,
-	       ctx->total_requests);
-}
-#endif

+ 6 - 3
src/main.c

@@ -2610,12 +2610,15 @@ main(int argc, char *argv[])
 	        g_server_name,
 	        mg_get_option(g_ctx, "listening_ports"),
 	        mg_get_option(g_ctx, "document_root"));
+
 	while (g_exit_flag == 0) {
-        /* TODO: Add Interface - call it here just for test:
-         * printctxinfo(g_ctx);
-         */
+		char buffer[1024];
+		mg_get_context_info(g_ctx, buffer, sizeof(buffer));
+		puts(buffer);
+
 		sleep(1);
 	}
+
 	fprintf(stdout,
 	        "Exiting on signal %d, waiting for all threads to finish...",
 	        g_exit_flag);