mirror of
https://github.com/3proxy/3proxy.git
synced 2026-10-17 00:55:47 +08:00
Count the traffic of each listener
Some checks failed
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Has been cancelled
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-latest) (push) Has been cancelled
C/C++ CI MacOS / ${{ matrix.target }} (macos-15) (push) Has been cancelled
C/C++ CI Windows / ${{ matrix.target }} (windows-2022) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (macos-15) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-latest) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (windows-2022) (push) Has been cancelled
C/C++ CI cmake / ubuntu-latest (wolfSSL) (push) Has been cancelled
Some checks failed
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Has been cancelled
C/C++ CI Linux / ${{ matrix.target }} (ubuntu-latest) (push) Has been cancelled
C/C++ CI MacOS / ${{ matrix.target }} (macos-15) (push) Has been cancelled
C/C++ CI Windows / ${{ matrix.target }} (windows-2022) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (macos-15) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-24.04-arm) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (ubuntu-latest) (push) Has been cancelled
C/C++ CI cmake / ${{ matrix.target }} (windows-2022) (push) Has been cancelled
C/C++ CI cmake / ubuntu-latest (wolfSSL) (push) Has been cancelled
A listener counts the traffic of its clients as it is logged: bytes from servers (%I) and from clients (%O). clearstat(), which every log writer calls once a line is logged, as well as lognone and logradius, adds the counts to the client's listener before clearing them, through listenertrafficfunc, set where services have listeners and NULL in the standalone binaries. The admin services page shows them as listenertrafin and listenertrafout. The takeover case checks that they go on through three reloads. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
6e12c2ce63
commit
67a73a4132
@ -559,6 +559,7 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
|
||||
_3proxy_mutex_init(&confref_mutex);
|
||||
_3proxy_mutex_init(&listener_mutex);
|
||||
reattachfunc = reattach;
|
||||
listenertrafficfunc = listenertraffic;
|
||||
_3proxy_mutex_init(&runningservices_mutex);
|
||||
_3proxy_mutex_init(&bandlim_mutex);
|
||||
_3proxy_mutex_init(&connlim_mutex);
|
||||
|
||||
@ -234,6 +234,7 @@ struct extparam confboot = {
|
||||
struct extparam *conf = &confboot;
|
||||
struct extparam *runconf = &confboot;
|
||||
int (*reattachfunc)(struct clientparam *param, int auth) = NULL;
|
||||
void (*listenertrafficfunc)(struct clientparam *param) = NULL;
|
||||
|
||||
/* Authorizes a request on a connection which may outlive a reload, an HTTP
|
||||
one kept alive: as a client of the service whose rules apply now, the
|
||||
|
||||
@ -538,6 +538,14 @@ static void * ef_server_listenerprocessed(struct node * node){
|
||||
return listenerprocessed((struct srvparam *)node->value);
|
||||
}
|
||||
|
||||
static void * ef_server_listenertrafin(struct node * node){
|
||||
return listenertrafin((struct srvparam *)node->value);
|
||||
}
|
||||
|
||||
static void * ef_server_listenertrafout(struct node * node){
|
||||
return listenertrafout((struct srvparam *)node->value);
|
||||
}
|
||||
|
||||
static void * ef_server_childcount(struct node * node){
|
||||
return &((struct srvparam *)node->value) -> childcount;
|
||||
}
|
||||
@ -896,6 +904,8 @@ static struct property prop_server[] = {
|
||||
{"childcount", ef_server_childcount, TYPE_INTEGER, "number of servers connected"},
|
||||
{"listenerclients", ef_server_listenerclients, TYPE_UNSIGNED64, "clients connected to the listening socket, of its services old and new"},
|
||||
{"listenerprocessed", ef_server_listenerprocessed, TYPE_UNSIGNED64, "clients of the listening socket done with"},
|
||||
{"listenertrafin", ef_server_listenertrafin, TYPE_UNSIGNED64, "bytes from servers to the clients of the listening socket, as logged"},
|
||||
{"listenertrafout", ef_server_listenertrafout, TYPE_UNSIGNED64, "bytes from the clients of the listening socket, as logged"},
|
||||
{"maxchild", ef_server_maxchild, TYPE_INTEGER, "max concurrent connections"},
|
||||
{"backlog", ef_server_backlog, TYPE_INTEGER, "listen backlog"},
|
||||
{"needuser", ef_server_needuser, TYPE_INTEGER, "require user authentication"},
|
||||
|
||||
@ -25,6 +25,9 @@ void dolog(struct clientparam * param, const unsigned char *s){
|
||||
|
||||
|
||||
void clearstat(struct clientparam * param) {
|
||||
/* the traffic logged, or dropped, counted for the listener first */
|
||||
if(param->srv && listenertrafficfunc && (param->statssrv64 || param->statscli64))
|
||||
(*listenertrafficfunc)(param);
|
||||
|
||||
#ifdef _WIN32
|
||||
struct timeb tb;
|
||||
|
||||
@ -406,6 +406,11 @@ extern int (*reattachfunc)(struct clientparam *param, int auth);
|
||||
int clientauth(struct clientparam *param);
|
||||
uint64_t *listenerclients(struct srvparam *srv);
|
||||
uint64_t *listenerprocessed(struct srvparam *srv);
|
||||
uint64_t *listenertrafin(struct srvparam *srv);
|
||||
uint64_t *listenertrafout(struct srvparam *srv);
|
||||
void listenertraffic(struct clientparam *param);
|
||||
/* listenertraffic() where services have listeners, NULL elsewhere */
|
||||
extern void (*listenertrafficfunc)(struct clientparam *param);
|
||||
struct passwords * copypwl (struct passwords *pwl);
|
||||
void freepwl(struct passwords *pw);
|
||||
int copyfilter(struct filter *, struct srvparam *srv);
|
||||
|
||||
@ -906,6 +906,9 @@ struct listener {
|
||||
/* its clients, whichever of its services, old or new, they came to:
|
||||
those connected now, and those done with */
|
||||
uint64_t clients, processed;
|
||||
/* the traffic of its clients as logged: from the server (%I) and
|
||||
from the client (%O) */
|
||||
uint64_t trafin, trafout;
|
||||
_3proxy_mutex_t count_mutex;
|
||||
};
|
||||
|
||||
@ -923,6 +926,18 @@ static void listenercount(struct srvparam *srv, int delta){
|
||||
_3proxy_mutex_unlock(&l->count_mutex);
|
||||
}
|
||||
|
||||
/* The traffic of a client, about to be cleared once logged, counted for
|
||||
its listener. */
|
||||
void listenertraffic(struct clientparam *param){
|
||||
struct listener *l = param->srv->listener;
|
||||
|
||||
if(!l) return;
|
||||
_3proxy_mutex_lock(&l->count_mutex);
|
||||
l->trafin += param->statssrv64;
|
||||
l->trafout += param->statscli64;
|
||||
_3proxy_mutex_unlock(&l->count_mutex);
|
||||
}
|
||||
|
||||
static uint64_t nocount = 0;
|
||||
|
||||
/* The counters of a running service's listener, for the admin pages; the
|
||||
@ -934,6 +949,14 @@ uint64_t *listenerclients(struct srvparam *srv){
|
||||
uint64_t *listenerprocessed(struct srvparam *srv){
|
||||
return srv->listener? &srv->listener->processed : &nocount;
|
||||
}
|
||||
|
||||
uint64_t *listenertrafin(struct srvparam *srv){
|
||||
return srv->listener? &srv->listener->trafin : &nocount;
|
||||
}
|
||||
|
||||
uint64_t *listenertrafout(struct srvparam *srv){
|
||||
return srv->listener? &srv->listener->trafout : &nocount;
|
||||
}
|
||||
static struct listener *listeners = NULL;
|
||||
_3proxy_mutex_t listener_mutex;
|
||||
|
||||
|
||||
@ -76,15 +76,25 @@ def run(t):
|
||||
page = t.http(f"http://127.0.0.1:{adm}/S").text
|
||||
m = re.search(r"type of the service/client</description><value><!\[CDATA\[" + service +
|
||||
r"\]\].*?<name>listenerclients</name>.*?CDATA\[(\d+)\]"
|
||||
r".*?<name>listenerprocessed</name>.*?CDATA\[(\d+)\]", page, re.S)
|
||||
return (int(m.group(1)), int(m.group(2))) if m else (None, None)
|
||||
r".*?<name>listenerprocessed</name>.*?CDATA\[(\d+)\]"
|
||||
r".*?<name>listenertrafin</name>.*?CDATA\[(\d+)\]"
|
||||
r".*?<name>listenertrafout</name>.*?CDATA\[(\d+)\]", page, re.S)
|
||||
return tuple(int(v) for v in m.groups()) if m else (None,) * 4
|
||||
|
||||
clients, processed = listener_counts("PROXY")
|
||||
clients, processed, trafin, trafout = listener_counts("PROXY")
|
||||
t.eq(0, clients, "no client is connected to the proxy's listener after the run")
|
||||
total = done["ok"] + done["failed"]
|
||||
t.ok(f"its count of clients done with goes on through the reloads ({processed} of {total})") \
|
||||
if processed is not None and processed >= total else \
|
||||
t.fail("its count of clients done with goes on through the reloads", f"at least {total}", processed)
|
||||
# and the traffic as logged: each answer brings 2000 bytes of body, each
|
||||
# request a few dozen bytes
|
||||
t.ok(f"the traffic from servers is counted through the reloads ({trafin} bytes)") \
|
||||
if trafin is not None and trafin >= 2000 * done["ok"] else \
|
||||
t.fail("the traffic from servers is counted through the reloads", f"at least {2000 * done['ok']}", trafin)
|
||||
t.ok(f"and the traffic from clients ({trafout} bytes)") \
|
||||
if trafout is not None and trafout >= 50 * done["ok"] else \
|
||||
t.fail("and the traffic from clients", f"at least {50 * done['ok']}", trafout)
|
||||
|
||||
# --- UDP: the socket is handed over too, and a session of the old
|
||||
# service goes on through it, its datagrams forwarded by the new one ---
|
||||
|
||||
Loading…
Reference in New Issue
Block a user