Skip to content

Commit 65a6e17

Browse files
authored
Fix statistics
1 parent 8239f2d commit 65a6e17

File tree

1 file changed

+159
-159
lines changed

1 file changed

+159
-159
lines changed

container/stats.py

Lines changed: 159 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -1,159 +1,159 @@
1-
2-
from dataclasses import dataclass, asdict
3-
import os
4-
from pathlib import Path
5-
import sqlite3
6-
import time
7-
from typing import Any
8-
9-
from utils import FileDataInputStream, FileDataOutputStream
10-
from timer import Timer # type: ignore
11-
12-
13-
@dataclass
14-
class Counters:
15-
hit: int = 0
16-
bytes: int = 0
17-
qps: int = 0
18-
bandwidth: int = 0
19-
20-
cache: Path = Path("./cache")
21-
cache.mkdir(exist_ok=True, parents=True)
22-
23-
db: sqlite3.Connection = sqlite3.Connection("./cache/stats.db")
24-
db.execute("create table if not exists `Stats`(Time numeric not null, hits numeric default 0, bytes numeric default 0, qps numeric default 0, bandwidth numeric default 0)")
25-
db.commit()
26-
counter = Counters()
27-
last_counter = Counters()
28-
last_time: int = 0
29-
def write():
30-
global counter, last_counter
31-
with open("./cache/stats_count.bin", "wb") as w:
32-
f = FileDataOutputStream(w)
33-
f.writeVarInt(counter.hit)
34-
f.writeVarInt(counter.bytes)
35-
f.writeVarInt(counter.qps)
36-
f.writeVarInt(counter.bandwidth)
37-
f.writeVarInt(last_counter.hit)
38-
f.writeVarInt(last_counter.bytes)
39-
40-
def read():
41-
global counter, last_counter
42-
if Path("./cache/stats_count.bin").exists():
43-
with open("./cache/stats_count.bin", "rb") as r:
44-
hit = 0
45-
bytes = 0
46-
qps = 0
47-
bandwidth = 0
48-
last_hit = 0
49-
last_bytes = 0
50-
try:
51-
f = FileDataInputStream(r)
52-
hit += f.readVarInt()
53-
bytes += f.readVarInt()
54-
qps += f.readVarInt()
55-
bandwidth += f.readVarInt()
56-
last_hit += f.readVarInt()
57-
last_bytes += f.readVarInt()
58-
counter.hit += hit
59-
counter.bytes += bytes
60-
counter.qps += qps
61-
counter.bandwidth += bandwidth
62-
last_counter.hit += last_hit
63-
last_counter.bytes += last_bytes
64-
except:
65-
...
66-
67-
def execute(cmd: str, *params) -> None:
68-
global db
69-
db.execute(cmd, params)
70-
db.commit()
71-
72-
def executemany(*cmds: tuple[str, tuple[Any, ...]]) -> None:
73-
global db
74-
for cmd in cmds:
75-
db.execute(*cmd)
76-
db.commit()
77-
78-
def query(cmd: str, *params) -> list[Any]:
79-
global db
80-
cur = db.execute(cmd, params)
81-
return cur.fetchone() or []
82-
83-
def queryAllData(cmd: str, *params) -> list[tuple]:
84-
global db
85-
cur = db.execute(cmd, params)
86-
return cur.fetchall() or []
87-
88-
def exists(cmd: str, *params) -> bool:
89-
return len(query(cmd, *params)) != 0
90-
91-
def columns(table):
92-
return [q[0] for q in queryAllData(f'SHOW COLUMNS FROM {table}')]
93-
94-
async def addColumns(table, params, data, default=None):
95-
if params not in columns(table):
96-
execute(f'ALTER TABLE {table} ADD COLUMN {params} {data}')
97-
if default is not None:
98-
execute(f'UPDATE {table} SET {params}={default}')
99-
100-
def write_database():
101-
global last_time, counter, extend_counter
102-
hits = counter.hit
103-
bytes = counter.bytes
104-
qps = counter.qps
105-
bandwidth = counter.bandwidth
106-
if hits == bytes == qps == bandwidth == 0:
107-
return
108-
t = int(time.time() // 3600)
109-
if last_time != t and not exists("select `Time` from `Stats` where `Time` = ?", t):
110-
execute("insert into `Stats`(`Time`) values (?)", t)
111-
executemany(("update `Stats` set `hits` = ?, `bytes` = ?, `qps` = ? where `Time` = ?", (hits, bytes, qps, t)),
112-
("update `Stats` set `bandwidth` = ? where `Time` = ? and `bandwidth` < ?", (bandwidth, t, bandwidth)))
113-
counter.bandwidth = 0
114-
if last_time != t:
115-
counter.hit = 0
116-
counter.bytes = 0
117-
counter.bandwidth = 0
118-
counter.qps = 0
119-
last_counter.hit = 0
120-
last_counter.bytes = 0
121-
last_time = t
122-
123-
def hourly():
124-
t = int(time.time() // 86400) * 24
125-
data = []
126-
for r in queryAllData("select `Time`, `hits`, `bytes`, `qps`, `bandwidth` from `Stats` where `Time` >= ?", t):
127-
hour = r[0] - t + int(os.environ["UTC"])
128-
data.append(
129-
{"_hour": hour,
130-
"hits": r[1],
131-
"bytes": r[2],
132-
"qps": r[3],
133-
"bandwidth": r[4]
134-
}
135-
)
136-
return data
137-
138-
def days():
139-
t = (int(time.time() // 86400) - 30) * 24
140-
r = queryAllData("select `Time`, `hits`, `bytes`, `qps`, `bandwidth` from `Stats` where `Time` >= ?", t)
141-
data = []
142-
days: dict[int, Counters] = {}
143-
for r in queryAllData("select `Time`, `hits`, `bytes`, `qps`, `bandwidth` from `Stats` where `Time` >= ?", t):
144-
hour = (r[0] - t + int(os.environ["UTC"])) // 24
145-
if hour not in days:
146-
days[hour] = Counters()
147-
days[hour].hit += r[1]
148-
days[hour].bytes += r[2]
149-
days[hour].qps += r[3]
150-
days[hour].bandwidth += r[4]
151-
for day in sorted(days.keys()):
152-
data.append({
153-
"_day": day,
154-
**asdict(days[day])
155-
})
156-
return data
157-
read()
158-
Timer.repeat(write, (), 0.01, 0.1)
159-
Timer.repeat(write_database, (), 1, 1)
1+
2+
from dataclasses import dataclass, asdict
3+
import os
4+
from pathlib import Path
5+
import sqlite3
6+
import time
7+
from typing import Any
8+
9+
from utils import FileDataInputStream, FileDataOutputStream
10+
from timer import Timer # type: ignore
11+
12+
13+
@dataclass
14+
class Counters:
15+
hit: int = 0
16+
bytes: int = 0
17+
qps: int = 0
18+
bandwidth: int = 0
19+
20+
cache: Path = Path("./cache")
21+
cache.mkdir(exist_ok=True, parents=True)
22+
23+
db: sqlite3.Connection = sqlite3.Connection("./cache/stats.db")
24+
db.execute("create table if not exists `Stats`(Time numeric not null, hits numeric default 0, bytes numeric default 0, qps numeric default 0, bandwidth numeric default 0)")
25+
db.commit()
26+
counter = Counters()
27+
last_counter = Counters()
28+
last_time: int = 0
29+
def write():
30+
global counter, last_counter
31+
with open("./cache/stats_count.bin", "wb") as w:
32+
f = FileDataOutputStream(w)
33+
f.writeVarInt(counter.hit)
34+
f.writeVarInt(counter.bytes)
35+
f.writeVarInt(counter.qps)
36+
f.writeVarInt(counter.bandwidth)
37+
f.writeVarInt(last_counter.hit)
38+
f.writeVarInt(last_counter.bytes)
39+
40+
def read():
41+
global counter, last_counter
42+
if Path("./cache/stats_count.bin").exists():
43+
with open("./cache/stats_count.bin", "rb") as r:
44+
hit = 0
45+
bytes = 0
46+
qps = 0
47+
bandwidth = 0
48+
last_hit = 0
49+
last_bytes = 0
50+
try:
51+
f = FileDataInputStream(r)
52+
hit += f.readVarInt()
53+
bytes += f.readVarInt()
54+
qps += f.readVarInt()
55+
bandwidth += f.readVarInt()
56+
last_hit += f.readVarInt()
57+
last_bytes += f.readVarInt()
58+
counter.hit += hit
59+
counter.bytes += bytes
60+
counter.qps += qps
61+
counter.bandwidth += bandwidth
62+
last_counter.hit += last_hit
63+
last_counter.bytes += last_bytes
64+
except:
65+
...
66+
67+
def execute(cmd: str, *params) -> None:
68+
global db
69+
db.execute(cmd, params)
70+
db.commit()
71+
72+
def executemany(*cmds: tuple[str, tuple[Any, ...]]) -> None:
73+
global db
74+
for cmd in cmds:
75+
db.execute(*cmd)
76+
db.commit()
77+
78+
def query(cmd: str, *params) -> list[Any]:
79+
global db
80+
cur = db.execute(cmd, params)
81+
return cur.fetchone() or []
82+
83+
def queryAllData(cmd: str, *params) -> list[tuple]:
84+
global db
85+
cur = db.execute(cmd, params)
86+
return cur.fetchall() or []
87+
88+
def exists(cmd: str, *params) -> bool:
89+
return len(query(cmd, *params)) != 0
90+
91+
def columns(table):
92+
return [q[0] for q in queryAllData(f'SHOW COLUMNS FROM {table}')]
93+
94+
async def addColumns(table, params, data, default=None):
95+
if params not in columns(table):
96+
execute(f'ALTER TABLE {table} ADD COLUMN {params} {data}')
97+
if default is not None:
98+
execute(f'UPDATE {table} SET {params}={default}')
99+
100+
def write_database():
101+
global last_time, counter
102+
hits = counter.hit
103+
bytes = counter.bytes
104+
qps = counter.qps
105+
bandwidth = counter.bandwidth
106+
if hits == bytes == qps == bandwidth == 0:
107+
return
108+
t = int(time.time() // 3600)
109+
if last_time != t and not exists("select `Time` from `Stats` where `Time` = ?", t):
110+
execute("insert into `Stats`(`Time`) values (?)", t)
111+
executemany(("update `Stats` set `hits` = ?, `bytes` = ?, `qps` = ? where `Time` = ?", (hits, bytes, qps, t)),
112+
("update `Stats` set `bandwidth` = ? where `Time` = ? and `bandwidth` < ?", (bandwidth, t, bandwidth)))
113+
counter.bandwidth = 0
114+
if last_time != 0 and last_time != t:
115+
counter.hit = 0
116+
counter.bytes = 0
117+
counter.bandwidth = 0
118+
counter.qps = 0
119+
last_counter.hit = 0
120+
last_counter.bytes = 0
121+
last_time = t
122+
123+
def hourly():
124+
t = int(time.time() // 86400) * 24
125+
data = []
126+
for r in queryAllData("select `Time`, `hits`, `bytes`, `qps`, `bandwidth` from `Stats` where `Time` >= ?", t):
127+
hour = r[0] - t + int(os.environ["UTC"])
128+
data.append(
129+
{"_hour": hour,
130+
"hits": r[1],
131+
"bytes": r[2],
132+
"qps": r[3],
133+
"bandwidth": r[4]
134+
}
135+
)
136+
return data
137+
138+
def days():
139+
t = (int(time.time() // 86400) - 30) * 24
140+
r = queryAllData("select `Time`, `hits`, `bytes`, `qps`, `bandwidth` from `Stats` where `Time` >= ?", t)
141+
data = []
142+
days: dict[int, Counters] = {}
143+
for r in queryAllData("select `Time`, `hits`, `bytes`, `qps`, `bandwidth` from `Stats` where `Time` >= ?", t):
144+
hour = (r[0] - t + int(os.environ["UTC"])) // 24
145+
if hour not in days:
146+
days[hour] = Counters()
147+
days[hour].hit += r[1]
148+
days[hour].bytes += r[2]
149+
days[hour].qps += r[3]
150+
days[hour].bandwidth += r[4]
151+
for day in sorted(days.keys()):
152+
data.append({
153+
"_day": day,
154+
**asdict(days[day])
155+
})
156+
return data
157+
Timer.repeat(write, (), 0.01, 0.1)
158+
Timer.repeat(write_database, (), 1, 1)
159+
read()

0 commit comments

Comments
 (0)