Browse Source

Even more statistics data (#243)

bel2125 8 năm trước cách đây
mục cha
commit
2cc3144b85
3 tập tin đã thay đổi với 162 bổ sung41 xóa
  1. 42 4
      src/civetweb.c
  2. 83 26
      src/mod_lua.inl
  3. 37 11
      test/page_status.lua

+ 42 - 4
src/civetweb.c

@@ -2284,6 +2284,8 @@ struct mg_context {
 	int64_t total_connections;
 	int64_t total_requests;
 	struct mg_memory_stat ctx_memory;
+	int64_t total_data_read;
+	int64_t total_data_written;
 #endif
 };
 
@@ -14116,8 +14118,9 @@ reset_per_request_attributes(struct mg_connection *conn)
 	}
 	conn->connection_type = 0; /* Not yet a valid request/response */
 
-	conn->path_info = NULL;
 	conn->num_bytes_sent = conn->consumed_content = 0;
+
+	conn->path_info = NULL;
 	conn->status_code = -1;
 	conn->is_chunked = 0;
 	conn->must_close = 0;
@@ -15473,8 +15476,14 @@ process_new_connection(struct mg_connection *conn)
 				conn->conn_state = 4; /* processing */
 #endif
 				handle_request(conn);
+
 #if defined(USE_SERVER_STATS)
 				conn->conn_state = 5; /* processed */
+
+				mg_atomic_add(&(conn->ctx->total_data_read),
+				              conn->consumed_content);
+				mg_atomic_add(&(conn->ctx->total_data_written),
+				              conn->num_bytes_sent);
 #endif
 
 				DEBUG_TRACE("%s", "handle_request done");
@@ -16599,11 +16608,13 @@ mg_get_system_info_impl(char *buffer, int buflen)
 	const char *eol = "\n";
 #endif
 
-	if (buffer == NULL) {
+	if ((buffer == NULL) || (buflen < 1)) {
 		/* Avoid some warning (although, if some dillweed supplies
 		 * buffer==NULL combined with buflen>0, he deserves a crash).
 		 */
 		buflen = 0;
+	} else {
+		*buffer = 0;
 	}
 
 	/* Server version */
@@ -16947,8 +16958,10 @@ mg_get_context_info_impl(const struct mg_context *ctx, char *buffer, int buflen)
 	const char *eoobj = "}";
 	int reserved_len = (int)strlen(eoobj) + (int)strlen(eol);
 
-	if ((buffer == NULL) || (buflen < 10)) {
+	if ((buffer == NULL) || (buflen < 1)) {
 		buflen = 0;
+	} else {
+		*buffer = 0;
 	}
 
 	mg_snprintf(NULL, NULL, block, sizeof(block), "{%s", eol);
@@ -17031,6 +17044,29 @@ mg_get_context_info_impl(const struct mg_context *ctx, char *buffer, int buflen)
 		}
 	}
 
+	/* Data information */
+	if (ctx) {
+		mg_snprintf(NULL,
+		            NULL,
+		            block,
+		            sizeof(block),
+		            "\"data\" : {%s"
+		            "\"read\" : %" INT64_FMT "%s,"
+		            "\"written\" : %" INT64_FMT "%s"
+		            "},%s",
+		            eol,
+		            ctx->total_data_read,
+		            eol,
+		            ctx->total_data_written,
+		            eol,
+		            eol);
+
+		context_info_length += (int)strlen(block);
+		if (context_info_length + reserved_len < buflen) {
+			strcat0(buffer, block);
+		}
+	}
+
 	/* Execution time information */
 	if (ctx) {
 		char start_time_str[64] = {0};
@@ -17106,8 +17142,10 @@ mg_get_connection_info_impl(const struct mg_context *ctx,
 	const char *eoobj = "}";
 	int reserved_len = (int)strlen(eoobj) + (int)strlen(eol);
 
-	if ((buffer == NULL) || (buflen < 10)) {
+	if ((buffer == NULL) || (buflen < 1)) {
 		buflen = 0;
+	} else {
+		*buffer = 0;
 	}
 
 	if ((ctx == NULL) || (idx < 0)) {

+ 83 - 26
src/mod_lua.inl

@@ -1035,13 +1035,17 @@ lsp_get_info(lua_State *L)
 			if (!mg_strcasecmp(arg1, "system")) {
 				/* Get system info */
 				len = mg_get_system_info(NULL, 0);
-				buf = mg_malloc(len + 64);
-				if (!buf) {
-					return luaL_error(L, "OOM in get_info() call");
+				if (len > 0) {
+					buf = mg_malloc(len + 64);
+					if (!buf) {
+						return luaL_error(L, "OOM in get_info() call");
+					}
+					len = mg_get_system_info(buf, len + 63);
+					lua_pushlstring(L, buf, len);
+					mg_free(buf);
+				} else {
+					lua_pushstring(L, "");
 				}
-				len = mg_get_system_info(buf, len + 63);
-				lua_pushlstring(L, buf, len);
-				mg_free(buf);
 				return 1;
 			}
 			if (!mg_strcasecmp(arg1, "context")) {
@@ -1053,32 +1057,39 @@ lsp_get_info(lua_State *L)
 
 				/* Get context info for server context */
 				len = mg_get_context_info(ctx, NULL, 0);
-				buf = mg_malloc(len + 64);
-				if (!buf) {
-					return luaL_error(L, "OOM in get_info() call");
+				if (len > 0) {
+					buf = mg_malloc(len + 64);
+					if (!buf) {
+						return luaL_error(L, "OOM in get_info() call");
+					}
+					len = mg_get_context_info(ctx, buf, len + 63);
+					lua_pushlstring(L, buf, len);
+					mg_free(buf);
+				} else {
+					lua_pushstring(L, "");
 				}
-				len = mg_get_context_info(ctx, buf, len + 63);
-				lua_pushlstring(L, buf, len);
-				mg_free(buf);
 				return 1;
 			}
 			if (!mg_strcasecmp(arg1, "common")) {
 				/* Get context info for NULL context */
 				len = mg_get_context_info(NULL, NULL, 0);
-				buf = mg_malloc(len + 64);
-				if (!buf) {
-					return luaL_error(L, "OOM in get_info() call");
+				if (len > 0) {
+					buf = mg_malloc(len + 64);
+					if (!buf) {
+						return luaL_error(L, "OOM in get_info() call");
+					}
+					len = mg_get_context_info(NULL, buf, len + 63);
+					lua_pushlstring(L, buf, len);
+					mg_free(buf);
+				} else {
+					lua_pushstring(L, "");
 				}
-				len = mg_get_context_info(NULL, buf, len + 63);
-				lua_pushlstring(L, buf, len);
-				mg_free(buf);
 				return 1;
 			}
 			return 0;
 		}
 	}
 
-#ifdef MG_EXPERIMENTAL_INTERFACES
 	if (num_args == 2) {
 		type1 = lua_type(L, 1);
 		type2 = lua_type(L, 2);
@@ -1101,26 +1112,70 @@ lsp_get_info(lua_State *L)
 				/* Lua uses 1 based index, C uses 0 based index */
 				idx--;
 
+#ifdef MG_EXPERIMENTAL_INTERFACES
 				len = mg_get_connection_info(ctx, idx, NULL, 0);
-				buf = mg_malloc(len + 64);
-				if (!buf) {
-					return luaL_error(L, "OOM in get_info() call");
+				if (len > 0) {
+					buf = mg_malloc(len + 64);
+					if (!buf) {
+						return luaL_error(L, "OOM in get_info() call");
+					}
+					len = mg_get_connection_info(ctx, idx, buf, len + 63);
+					lua_pushlstring(L, buf, len);
+					mg_free(buf);
+				} else {
+					lua_pushstring(L, "");
 				}
-				len = mg_get_connection_info(ctx, idx, buf, len + 63);
-				lua_pushlstring(L, buf, len);
-				mg_free(buf);
+#else
+				(void)ctx;
+				(void)idx;
+				lua_pushstring(L, "");
+#endif
+
 				return 1;
 			}
 			return 0;
 		}
 	}
-#endif
 
 	/* Syntax error */
 	return luaL_error(L, "invalid get_info() call");
 }
 
 
+/* mg.get_option */
+static int
+lsp_get_option(lua_State *L)
+{
+	int num_args = lua_gettop(L);
+	int type1;
+	const char *arg1;
+	const char *data;
+
+	/* Get context */
+	struct mg_context *ctx;
+	lua_pushlightuserdata(L, (void *)&lua_regkey_ctx);
+	lua_gettable(L, LUA_REGISTRYINDEX);
+	ctx = (struct mg_context *)lua_touserdata(L, -1);
+
+	if (num_args == 1) {
+		type1 = lua_type(L, 1);
+		if (type1 == LUA_TSTRING) {
+			arg1 = lua_tostring(L, 1);
+			/* Get option according to argument */
+			data = mg_get_option(ctx, arg1);
+			if (data) {
+				lua_pushstring(L, data);
+				return 1;
+			}
+			return 0;
+		}
+	}
+
+	/* Syntax error */
+	return luaL_error(L, "invalid get_option() call");
+}
+
+
 /* UUID library and function pointer */
 union {
 	void *p;
@@ -1644,6 +1699,8 @@ prepare_lua_environment(struct mg_context *ctx,
 	reg_function(L, "get_response_code_text", lsp_get_response_code_text);
 	reg_function(L, "random", lsp_random);
 	reg_function(L, "get_info", lsp_get_info);
+	reg_function(L, "get_option", lsp_get_option);
+
 	if (pf_uuid_generate.f) {
 		reg_function(L, "uuid", lsp_uuid);
 	}

+ 37 - 11
test/page_status.lua

@@ -1,14 +1,40 @@
 mg.write("HTTP/1.0 200 OK\r\n")
-mg.write("Content-Type: text/html\r\n")
+
+-- MIME type: https://www.ietf.org/rfc/rfc4627.txt, chapter 6
+mg.write("Content-Type: application/json\r\n")
+
 mg.write("\r\n")
-mg.write("<html><body><p>\r\n")
-mg.write(mg.get_info("system"))
-mg.write("</p>\r\n<p>\r\n")
-mg.write(mg.get_info("context"))
-mg.write("</p>\r\n<p>\r\n")
-mg.write(mg.get_info("common"))
-for i=1,100 do
-  mg.write("</p>\r\n<p>\r\n")
-  mg.write(mg.get_info("connection", i))
+
+num_threads = mg.get_option("num_threads")
+num_threads = tonumber(num_threads)
+
+
+function n(s) 
+  if ((type(s) == "string") and (#s > 0)) then 
+    return s 
+  else 
+    return "null" 
+  end
 end
-mg.write("</p></body></html>\r\n")
+
+
+mg.write("{\r\n\"system\" :\r\n")
+
+mg.write("\"")
+mg.write(n(mg.get_info("system")))
+mg.write("\"")
+
+mg.write(",\r\n\"summary\" :\r\n")
+mg.write(n(mg.get_info("context")))
+mg.write(",\r\n\"common\" :\r\n")
+mg.write(n(mg.get_info("common")))
+mg.write(",\r\n\"connections\" :\r\n[\r\n")
+
+  mg.write(n(mg.get_info("connection", 1)))
+
+for i=2,num_threads do
+  mg.write(",\r\n")
+  mg.write(n(mg.get_info("connection", i)))
+end
+mg.write("]\r\n}\r\n")
+