Files
OpenVPN-Monitoring-Simple/APP/__pycache__/openvpn_gatherer_v3.cpython-314.pyc

135 lines
23 KiB
Plaintext
Raw Normal View History

2026-01-09 01:05:50 +03:00
+
<00>`iW<00><00><><00>^RIt^RIt^RIt^RIt^RIt^RIHtHt^RIHt!RR4t !RR4t
] R8Xd]
!4t ] P4R#R#) <09>N)<02>datetime<6D> timedelta)<01>DatabaseManagerc<00>2a<00>]tRt^
toRtRtRtRtVtR#)<06>TimeSeriesAggregatorc<08>P<00>Wn\P!\4VnR#<00>N)<05> db_provider<65>logging<6E> getLogger<65>__name__<5F>logger)<02>selfr
s&&<26>APP/openvpn_gatherer_v3.py<70>__init__<5F>TimeSeriesAggregator.__init__ s<00><00>&<26><18><1D>'<27>'<27><08>1<><04> <0B>c <0C>6<00>VPRV R2W4WV34R#)u<>
Вставляет или обновляет запись в таблицу агрегации.
Использует ON CONFLICT для атомарного обновления счетчиков.
z
INSERT INTO a! (timestamp, client_id, bytes_received, bytes_sent)
VALUES (?, ?, ?, ?)
ON CONFLICT(timestamp, client_id) DO UPDATE SET
bytes_received = bytes_received + excluded.bytes_received,
bytes_sent = bytes_sent + excluded.bytes_sent
N)<01>execute)r<00>cursor<6F>table<6C> timestamp<6D> client_id<69>rx<72>txs&&&&&&&r<00>_upsert_bucket<65>#TimeSeriesAggregator._upsert_buckets.<00><00>
<0F><0E><0E><19><1E><07> <09> <0C> <18>B<EFBFBD> +<2B>  -rc  <0C><><00>V'gR#VP4pVP4p\P!4pVP ^^^^R7P R4pVP VP ^,,
pVP V^^^R7P R4pVP ^^^R7P R4pVPVP^,,
p VP V ^^R7P R4p
VPVP^,,
p VP V ^^R7P R4p ^p VF<>pVPR4pVfKVPR^4pVPR^4pV^8Xd
V^8XdKNVPVRW<>VV4VPVR W<>VV4VPVR
W<EFBFBD>VV4VPVR WVV4VPVR W_VV4V ^, p K<> VP4V ^8<>d VPPR V R24TP!4R# \d9pTPPRT 24TP4Rp?LPRp?ii;i TP!4i;i)uz
Распределяет инкременты трафика по временным слотам (5m, 15m, 1h, 6h, 1d).
N)<04>hour<75>minute<74>second<6E> microsecond<6E>%Y-%m-%d %H:%M:%S)r r!r"<00>db_id<69>bytes_received_inc<6E>bytes_sent_inc<6E>
stats_5min<EFBFBD> stats_15min<69> stats_hourly<6C>stats_6h<36> stats_dailyz$TS Aggregation: Updated buckets for z clientszError in TimeSeriesAggregator: )r
rr<00>now<6F>replace<63>strftimerr <00>getr<00>commitr<00>debug<75> Exception<6F>error<6F>rollback<63>close)r<00>client_updates<65>connrr,<00>ts_1d<31>hour_6h<36>ts_6h<36>ts_1h<31>min_15m<35>ts_15m<35>min_5m<35>ts_5m<35> updates_count<6E>clientrrr<00>es&& r<00> aggregate<74>TimeSeriesAggregator.aggregates{<00><00><1E> <12><13><1F><1F>!<21><04><15><1B><1B><1D><06><16>l<EFBFBD>l<EFBFBD>n<EFBFBD><03><14> <0B> <0B><11>1<EFBFBD>Q<EFBFBD>A<EFBFBD> <0B>F<>O<>O<>Pc<50>d<><05><16>(<28>(<28>c<EFBFBD>h<EFBFBD>h<EFBFBD><11>l<EFBFBD>+<2B><07><13> <0B> <0B><17><11>1<EFBFBD>!<21> <0B>L<>U<>U<>Vi<56>j<><05><14> <0B> <0B>1<EFBFBD>Q<EFBFBD>A<EFBFBD> <0B>><3E>G<>G<>H[<5B>\<5C><05><16>*<2A>*<2A><03>
<EFBFBD>
<EFBFBD>R<EFBFBD><0F>0<><07><14><1B><1B>G<EFBFBD>A<EFBFBD>1<EFBFBD><1B>E<>N<>N<>Ob<4F>c<><06><15><1A><1A>s<EFBFBD>z<EFBFBD>z<EFBFBD>A<EFBFBD>~<7E>.<2E><06><13> <0B> <0B>6<EFBFBD>!<21><11> <0B>C<>L<>L<>M`<60>a<><05>" <19><1D>M<EFBFBD>(<28><06>"<22>J<EFBFBD>J<EFBFBD>w<EFBFBD>/<2F> <09><1D>$<24><1C><1B>Z<EFBFBD>Z<EFBFBD> 4<>a<EFBFBD>8<><02><1B>Z<EFBFBD>Z<EFBFBD> 0<>!<21>4<><02><16><11>7<EFBFBD>r<EFBFBD>Q<EFBFBD>w<EFBFBD><1C><15>#<23>#<23>F<EFBFBD>L<EFBFBD>%<25>B<EFBFBD>PR<50>S<><14>#<23>#<23>F<EFBFBD>M<EFBFBD>6<EFBFBD>b<EFBFBD>RT<52>U<><14>#<23>#<23>F<EFBFBD>N<EFBFBD>E<EFBFBD>b<EFBFBD>RT<52>U<><14>#<23>#<23>F<EFBFBD>J<EFBFBD><05>"<22>b<EFBFBD>Q<><14>#<23>#<23>F<EFBFBD>M<EFBFBD>5<EFBFBD>R<EFBFBD>QS<51>T<><1D><11>"<22> <0A>+)<29>. <11>K<EFBFBD>K<EFBFBD>M<EFBFBD><1C>q<EFBFBD> <20><14> <0B> <0B>!<21>!<21>$H<><1D><0F>W_<57>"`<60>a<> <11>J<EFBFBD>J<EFBFBD>L<EFBFBD><4C> <19> <1C> <10>K<EFBFBD>K<EFBFBD> <1D> <1D> ?<3F><01>s<EFBFBD>C<> D<> <10>M<EFBFBD>M<EFBFBD>O<EFBFBD>O<EFBFBD><4F> <1C><> <11>J<EFBFBD>J<EFBFBD>L<EFBFBD>s+<00>C>I.<00>. J1<03>9.J,<03>'J4<00>,J1<03>1J4<00>4K)r
rN) r <00>
__module__<EFBFBD> __qualname__<5F>__firstlineno__rrrC<00>__static_attributes__<5F>__classdictcell__<5F><01> __classdict__s@rrr
s<00><><00><00>2<> -<2D>A<19>Arrc<00>ja<00>]tRt^`toRRltRtRtRRltRtRt Rt
R t R
t R t R tR tVtR#)<10>OpenVPNDataGathererc<08><><00>VPV4VnVP4RVn\P
!4\ ^R7,
P4Vn\P
!4\ ^R7,
P4Vn\V4Vn
VPP4\VPP4VnR#)N<><01>days)<0F> load_config<69>config<69> setup_logging<6E>last_check_timerr,r<00>date<74>last_cleanup_dater<00>
db_manager<EFBFBD> init_databaser<00>get_connection<6F> ts_aggregator)r<00> config_files&&rr<00>OpenVPNDataGatherer.__init__as<><00><00><1A>&<26>&<26>{<7B>3<><04> <0B> <0C><1A><1A><1C>#<23><04><1C>"*<2A>,<2C>,<2C>.<2E>9<EFBFBD>!<21>3D<33>"D<>!J<>!J<>!L<><04><1E>"*<2A>,<2C>,<2C>.<2E>9<EFBFBD>!<21>3D<33>"D<>!J<>!J<>!L<><04><1E>)<29>+<2B>6<><04><0F> <0C><0F><0F>%<25>%<25>'<27>2<>$<24>/<2F>/<2F>2P<32>2P<32>Q<><04>rc <0C><><00>\P!4pRRRRRRR/RR R
R R R R/RRRRR/RRRRRRRRRRRRR /R!R"R#R$R%/R&R'R(R)R*//p\PP V4'd<>VP V4R+pVP 4FuwrVVPV4'gVPV4R,pVP 4F2wrxVPWW4'dKVPWWV4R,pK4 Kw V'd=\VR-4;_uu_4p VPV 4R.R.R.4\R/V 24V#VP 4F wrVWbV&K \VR-4;_uu_4p VPV 4R.R.R.4\R0V 24V# +'giL|;i +'giL4;i \d<>p
\R1T
24TP 4FXwrVTPT4'gTPT4TP 4FwrxTPYWT4K KZ R.p
?
T#R.p
?
ii;i)2u}Загрузка конфигурации или создание дефолтной со сложной структурой<D0BE>api<70>hostz0.0.0.0<EFBFBD>port<72>5000r1<00>false<73>openvpn_monitor<6F>log_path<74>#/var/log/openvpn/openvpn-status.log<6F>db_pathzopenvpn_monitor.db<64>check_interval<61>10r <00>level<65>INFO<46>log_file<6C>openvpn_gatherer.log<6F> retention<6F>raw_retention_days<79>7<>agg_5m_retention_days<79>14<31>agg_15m_retention_days<79>28<32>agg_1h_retention_days<79>90<39>agg_6h_retention_days<79>180<38>agg_1d_retention_days<79>365<36> visualization<6F>refresh_interval<61>5<>max_display_rows<77>50<35> certificates<65>certificates_pathz/opt/ovpn/pki/issued<65>certificate_extensions<6E>crtFT<46>wNzUpdated configuration file: z$Created default configuration file: zError loading config: )<0F> configparser<65> ConfigParser<65>os<6F>path<74>exists<74>read<61>items<6D> has_section<6F> add_section<6F>
has_option<EFBFBD>set<65>open<65>write<74>printr2) rr[rR<00>defaults<74>updated<65>section<6F>options<6E>key<65>val<61>frBs && rrQ<00>OpenVPNDataGatherer.load_configqsd<00><00><1D>*<2A>*<2A>,<2C><06> <12><16> <09><16><06><17><17><0E>
<1E><1A>A<><19>/<2F> <20>$<24> <0E>
<16><17><16><1A>2<><0E> <18>$<24>c<EFBFBD>'<27><14>(<28>$<24>'<27><14>'<27><15>'<27><15> <0E> <1C>"<22>C<EFBFBD>"<22>D<EFBFBD><0E> <1B>#<23>%;<3B>(<28>%<25><0E>7
<EFBFBD><08>B 2<><11>w<EFBFBD>w<EFBFBD>~<7E>~<7E>k<EFBFBD>*<2A>*<2A><16> <0B> <0B>K<EFBFBD>(<28><1F><07>(0<><0E><0E>(8<>$<24>G<EFBFBD>!<21>-<2D>-<2D>g<EFBFBD>6<>6<><1E>*<2A>*<2A>7<EFBFBD>3<>"&<26><07>$+<2B>M<EFBFBD>M<EFBFBD>O<EFBFBD><08><03>%<25>0<>0<><17>><3E>><3E>"<22>J<EFBFBD>J<EFBFBD>w<EFBFBD>S<EFBFBD>9<>&*<2A>G<EFBFBD>%4<> )9<><1B><1D>k<EFBFBD>3<EFBFBD>/<2F>/<2F>1<EFBFBD><1E> <0C> <0C>Q<EFBFBD><0F>0<><19>8<><1B> <0A>F<>G<>$<16> <0A>)1<><0E><0E>(8<>$<24>G<EFBFBD>&-<2D>7<EFBFBD>O<EFBFBD>)9<><19>+<2B>s<EFBFBD>+<2B>+<2B>q<EFBFBD><1A>L<EFBFBD>L<EFBFBD><11>O<EFBFBD>,<2C><15><<3C>[<5B>M<EFBFBD>J<>K<><16> <0A>)0<>/<2F><>,<2C>+<2B><><19> 2<> <11>*<2A>1<EFBFBD>#<23>.<2E> /<2F>$,<2C>N<EFBFBD>N<EFBFBD>$4<> <20><07><1D>)<29>)<29>'<27>2<>2<><1A>&<26>&<26>w<EFBFBD>/<2F> '<27> <0A> <0A><0F>H<EFBFBD>C<EFBFBD><1A>J<EFBFBD>J<EFBFBD>w<EFBFBD>S<EFBFBD>1<>!0<>%5<> <16> <0A><> 2<>sb<00> $G<00>.A;G<00>.#G<00>G<00>&F,<05>8G<00>1G<00>F?<05>G<00>, F< <09>7G<00>? G <09>
G<00> I"<03>A:I<03>I"c<08><00>VPPRRRR7pVPPRRRR7p\PP V4pV'd<\PP V4'g\P !V4\P!\\VP44R\P!V4\P!4.R7\P!\4VnR
# \ d^p\#RT 24\P!\P$R 7\P!\4TnR
p?R
#R
p?ii;i) r rirj<00><01>fallbackrkrlz)%(asctime)s - %(levelname)s - %(message)s)ri<00>format<61>handlerszLogging setup failed: )riN)rRr/r<>r<><00>dirnamer<65><00>makedirsr <00> basicConfig<69>getattr<74>upper<65> FileHandler<65> StreamHandlerr r rr2r<>rj)r<00> log_levelrk<00>log_dirrBs& rrS<00>!OpenVPNDataGatherer.setup_logging<6E>s<00><00> 6<><1C> <0B> <0B><0F><0F> <09>7<EFBFBD>V<EFBFBD><0F>L<>I<EFBFBD><1B>{<7B>{<7B><EFBFBD><EFBFBD>y<EFBFBD>*<2A>G]<5D><EFBFBD>^<5E>H<EFBFBD><19>g<EFBFBD>g<EFBFBD>o<EFBFBD>o<EFBFBD>h<EFBFBD>/<2F>G<EFBFBD><16>r<EFBFBD>w<EFBFBD>w<EFBFBD>~<7E>~<7E>g<EFBFBD>6<>6<><12> <0B> <0B>G<EFBFBD>$<24> <13> <1F> <1F><1D>g<EFBFBD>y<EFBFBD><EFBFBD><EFBFBD>'8<>9<>B<><1B>'<27>'<27><08>1<><1B>)<29>)<29>+<2B><12> <0E>"<22>+<2B>+<2B>H<EFBFBD>5<>D<EFBFBD>K<EFBFBD><4B><18> 6<> <11>*<2A>1<EFBFBD>#<23>.<2E> /<2F> <13> <1F> <1F>g<EFBFBD>l<EFBFBD>l<EFBFBD> 3<>!<21>+<2B>+<2B>H<EFBFBD>5<>D<EFBFBD>K<EFBFBD>K<EFBFBD><4B> 6<>s&<00>A"D<00>%$D<00>
BD<00> F<03>*AF<03>FNc<08>P<00>VPPWVR7# Tu#;i)r<>)rRr/)rr<>r<><00>defaults&&&&r<00>get_config_value<75>$OpenVPNDataGatherer.get_config_value<75>s*<00><00> <1B><17>;<3B>;<3B>?<3F>?<3F>7<EFBFBD>'<27>?<3F>B<> B<><42> <1B><1A>N<EFBFBD>s<00><00>%c
 <0C>T<00>VPPR4VPP4pVP 4p.ROp^pVF<>wrVp\ VP RWg44pV^8<>gK*\P!4\VR7,
PR4p VPRV R2V 34VPp
V
^8<>gK<>VPPRV RV
R V R
24WJ, pK<> VP4V^8XdVPPR 4TP#4R # \d9p TPPR T 24TP!4R p ? LPR p ? ii;i TP#4i;i)uMОчистка данных согласно retention policies в config.iniz"Starting data cleanup procedure...rmrOr#z DELETE FROM z WHERE timestamp < ?zCleaned z
: removed z records older than z daysz#Cleanup finished: nothing to deletezCleanup Error: N))<03> usage_historyrn<00>)r'rp<00>)r(rr<00>)r)rt<00>Z)r*rv<00><>)r+rxim)r<00>inforWrYr<00>intr<74>rr,rr.r<00>rowcountr0r2r3r4r5) rr7r<00>retention_rules<65> total_deletedr<00>
config_key<EFBFBD> default_daysrP<00> cutoff_date<74>deletedrBs & r<00>cleanup_old_data<74>$OpenVPNDataGatherer.cleanup_old_data<74>sc<00><00> <0C> <0B> <0B><18><18>=<3D>><3E><13><EFBFBD><EFBFBD>-<2D>-<2D>/<2F><04><15><1B><1B><1D><06>
<EFBFBD><0F> <19><1D>M<EFBFBD>3B<33>/<2F><05><<3C><1A>4<EFBFBD>0<>0<><1B>j<EFBFBD>W<>X<><04><17>!<21>8<EFBFBD>#+<2B><<3C><<3C>><3E>I<EFBFBD>4<EFBFBD>4H<34>#H<>"R<>"R<>Sf<53>"g<>K<EFBFBD><1A>N<EFBFBD>N<EFBFBD>\<5C>%<25><17>8L<38>#M<>P[<5B>~<7E>^<5E>$<24>o<EFBFBD>o<EFBFBD>G<EFBFBD><1E><11>{<7B><1C> <0B> <0B>(<28>(<28>8<EFBFBD>E<EFBFBD>7<EFBFBD>*<2A>W<EFBFBD>I<EFBFBD>Ma<4D>bf<62>ag<61>gl<67>)m<>n<>%<25>0<> <0A>4C<01> <11>K<EFBFBD>K<EFBFBD>M<EFBFBD><1C><01>!<21><14> <0B> <0B> <20> <20>!F<>G<> <11>J<EFBFBD>J<EFBFBD>L<EFBFBD><4C> <19> <1C> <10>K<EFBFBD>K<EFBFBD> <1D> <1D><0F><01>s<EFBFBD>3<> 4<> <10>M<EFBFBD>M<EFBFBD>O<EFBFBD>O<EFBFBD><4F> <1C><> <11>J<EFBFBD>J<EFBFBD>L<EFBFBD>s8<00> )E<00>9AE<00>A#E<00> F<03>.F <03>F<00> F<03>F<00>F'c <0C>(<00>VPRRR4p.p\PPV4'g!VPP RV 24V#\ VR4;_uu_4pVF<>pVP4pVPR4'gK,VPR4p\V4^8<>gKOV^,R8wgK_R V^,P4R
V^,P4R \V^,P44R \V^,P44R R/pVPV4K<> RRR4VPPR\V4 R24V# \\3d+pTPP RT 24Rp?EKORp?ii;i +'giLx;i \ d*pTPP#RT 24Rp?T#Rp?ii;i)u<>
Парсинг лога версии 2 (CSV формат).
Ожидает формат: CLIENT_LIST,Common Name,Real Address,...,Bytes Received,Bytes Sent,...
rcrdrezLog file not found: <20>r<> CLIENT_LIST<53>,z Common Name<6D> common_name<6D> real_address<73>bytes_received<65>
bytes_sent<EFBFBD>status<75>ActivezError parsing client line: NzParsed z active clientszError parsing log file: )r<>r<>r<>r<>r<00>warningr<67><00>strip<69>
startswith<EFBFBD>split<69>lenr<6E><00>append<6E>
ValueError<EFBFBD>
IndexErrorr1r2r3)rrd<00>clients<74>file<6C>line<6E>partsrArBs& r<00>parse_log_file<6C>"OpenVPNDataGatherer.parse_log_files<><00><00>
<18>(<28>(<28>):<3A>J<EFBFBD>Hm<48>n<><08><14><07># ><3E><15>7<EFBFBD>7<EFBFBD>><3E>><3E>(<28>+<2B>+<2B><14> <0B> <0B>#<23>#<23>&:<3A>8<EFBFBD>*<2A>$E<>F<><1E><0E><15>h<EFBFBD><03>$<24>$<24><04> <20>D<EFBFBD><1F>:<3A>:<3A><<3C>D<EFBFBD><1F>?<3F>?<3F>=<3D>9<>9<> <20> <20>J<EFBFBD>J<EFBFBD>s<EFBFBD>O<EFBFBD>E<EFBFBD><1B>5<EFBFBD>z<EFBFBD>Q<EFBFBD><EFBFBD>5<EFBFBD><11>8<EFBFBD>}<7D>+D<>
S<01> -<2D>u<EFBFBD>Q<EFBFBD>x<EFBFBD>~<7E>~<7E>/?<3F> .<2E><05>a<EFBFBD><08><0E><0E>0@<40> 0<>#<23>e<EFBFBD>A<EFBFBD>h<EFBFBD>n<EFBFBD>n<EFBFBD>6F<36>2G<32> ,<2C>c<EFBFBD>%<25><01>(<28>.<2E>.<2E>2B<32>.C<> (<28>(<28> &<1E>F<EFBFBD>$<24>N<EFBFBD>N<EFBFBD>6<EFBFBD>2<>-!<21>%<25>6 <11>K<EFBFBD>K<EFBFBD> <1D> <1D><07><03>G<EFBFBD> <0C>~<7E>_<EFBFBD>E<> F<>
<17><0E><>!+<2B>J<EFBFBD>7<>S<01> <20>K<EFBFBD>K<EFBFBD>/<2F>/<2F>2M<32>a<EFBFBD>S<EFBFBD>0Q<30>R<>R<><52>S<01><>1%<25>$<24><>:<19> ><3E> <10>K<EFBFBD>K<EFBFBD> <1D> <1D> 8<><11><03><<3C> =<3D> =<3D><16><0E><> ><3E>sl<00>$G<00>G<00>G<00>0A G
<05> G
<05>BF <06>G
<05>0G<00> G <09>G <09>;G
<05>G <09>G
<05>
G <09>G<00> H<03>(H <03> Hc  <0C><><00>VPP4pVP4pVPR4/pVP 4F2pRV^,RV^,RV^,RV^,/WE^,&K4 \ 4pVEFKpVR,pVP V4VR,p VR,p
W<EFBFBD>9d<>WH,p V R,VR &W<>R,8d#T p VPPR
V R 24MW<>R,,
p W<>R,8d#T
p VPPR
V R 24MW<>R,,
p VPR VR,V V V V
V R,34W<>R&W<>R&K<>VPRVVR,V V
34VPpW<>R &^VR&^VR&VPPRV 24EKN VP4FUwr<>W<EFBFBD>9gK V R,R8XgKVPRV R,34VPPRV 24KW VP4VP4V# \d9pTPPRT 24TP4Rp?LPRp?ii;i TP4i;i)u[Обновление статусов и расчет инкрементов трафикаzQSELECT id, common_name, status, last_bytes_received, last_bytes_sent FROM clients<74>idr<64><00>last_bytes_received<65>last_bytes_sentr<74>r<>r<>r$zCounter reset detected for z (Recv)z (Sent)a3
UPDATE clients
SET status = 'Active',
real_address = ?,
total_bytes_received = total_bytes_received + ?,
total_bytes_sent = total_bytes_sent + ?,
last_bytes_received = ?,
last_bytes_sent = ?,
updated_at = CURRENT_TIMESTAMP,
last_activity = CURRENT_TIMESTAMP
WHERE id = ?
r<>r%r&a
INSERT INTO clients
(common_name, real_address, status, total_bytes_received, total_bytes_sent, last_bytes_received, last_bytes_sent)
VALUES (?, ?, 'Active', 0, 0, ?, ?)
zNew client added: r<>z<>
UPDATE clients
SET status = 'Disconnected', updated_at = CURRENT_TIMESTAMP
WHERE id = ?
zClient disconnected: zError updating client status: N)rWrYrr<00>fetchallr<6C><00>addrr<><00> lastrowidr<64>r0r2r3r4r5)r<00>active_clientsr7r<00>
db_clients<EFBFBD>row<6F> active_namesrA<00>name<6D> curr_recv<63> curr_sent<6E> db_client<6E>inc_recv<63>inc_sent<6E>new_idrBs&& r<00>update_client_status_and_bytes<65>2OpenVPNDataGatherer.update_client_status_and_bytes2s<><00><00><13><EFBFBD><EFBFBD>-<2D>-<2D>/<2F><04><15><1B><1B><1D><06>d <19> <12>N<EFBFBD>N<EFBFBD>n<> o<><1B>J<EFBFBD><1D><EFBFBD><EFBFBD>(<28><03><18>#<23>a<EFBFBD>&<26><1C>c<EFBFBD>!<21>f<EFBFBD>)<29>3<EFBFBD>q<EFBFBD>6<EFBFBD>%<25>s<EFBFBD>1<EFBFBD>v<EFBFBD> &<12>
<EFBFBD>q<EFBFBD>6<EFBFBD>"<22>)<29><1F>5<EFBFBD>L<EFBFBD>(<28><06><1D>m<EFBFBD>,<2C><04><1C> <20> <20><14>&<26>"<22>#3<>4<> <09>"<22><<3C>0<> <09><17>%<25> *<2A> 0<>I<EFBFBD>&/<2F><04>o<EFBFBD>F<EFBFBD>7<EFBFBD>O<EFBFBD>!<21>-B<>#C<>C<>#,<2C><08><1C> <0B> <0B>(<28>(<28>+F<>t<EFBFBD>f<EFBFBD>G<EFBFBD>)T<>U<>#,<2C>9N<39>/O<>#O<><08> <20>-><3E>#?<3F>?<3F>#,<2C><08><1C> <0B> <0B>(<28>(<28>+F<>t<EFBFBD>f<EFBFBD>G<EFBFBD>)T<>U<>#,<2C>9J<39>/K<>#K<><08><1B>N<EFBFBD>N<EFBFBD> $<18><1F>~<7E>.<2E> <20> <20>!<21>!<21>!<21>$<24><0F> <16><17>(4<<3C>/<2F>0<>/7<>+<2B>,<2C><1B>N<EFBFBD>N<EFBFBD>$<18>
<1D><1E>~<7E>.<2E>!<21>!<21> <16> <17>$<24>-<2D>-<2D>F<EFBFBD>&,<2C>7<EFBFBD>O<EFBFBD>34<33>F<EFBFBD>/<2F>0<>/0<>F<EFBFBD>+<2B>,<2C><18>K<EFBFBD>K<EFBFBD>$<24>$<24>'9<>$<24><16>%@<40>A<>I)<29>N$.<2E>#3<>#3<>#5<><0F><04><17>+<2B> <09>(<28>0C<30>x<EFBFBD>0O<30><1A>N<EFBFBD>N<EFBFBD>$<18>$<24>D<EFBFBD>/<2F>+<2B> -<2D>
<19>K<EFBFBD>K<EFBFBD>$<24>$<24>'<<3C>T<EFBFBD>F<EFBFBD>%C<>D<>$6<> <11>K<EFBFBD>K<EFBFBD>M<EFBFBD> <11>J<EFBFBD>J<EFBFBD>L<EFBFBD><1D><1D><> <19> <1C> <10>K<EFBFBD>K<EFBFBD> <1D> <1D> ><3E>q<EFBFBD>c<EFBFBD>B<> C<> <10>M<EFBFBD>M<EFBFBD>O<EFBFBD>O<EFBFBD><4F> <1C><> <11>J<EFBFBD>J<EFBFBD>L<EFBFBD>s7<00>G I,<00>> I,<00>A I,<00>, J/<03>7.J*<03>%J2<00>*J/<03>/J2<00>2Kc <0C><><00>V^8:dRp^VR,, pVF;pVPR^4V,VR&VPR^4V,VR&K= V#)u%Расчет скорости в Mbpsg<00>?i@Br%<00>bytes_received_rate_mbpsr&<00>bytes_sent_rate_mbps)r/)rr<><00> time_diff<66>factorrAs&&& r<00>calculate_rates<65>#OpenVPNDataGatherer.calculate_rates<65>sj<00><00> <14><01>><3E><1B>I<EFBFBD><13>i<EFBFBD>)<29>+<2B>,<2C><06><1D>F<EFBFBD>17<31><1A><1A><P<>RS<52>1T<31>W]<5D>1]<5D>F<EFBFBD>-<2D> .<2E>-3<>Z<EFBFBD>Z<EFBFBD>8H<38>!<21>-L<>v<EFBFBD>-U<>F<EFBFBD>)<29> *<2A><1E><17>rc  <0C>f<00>V'gR#VPP4pVP4pVFzpVPR4'gKVP RVR,VPR^4VPR^4VPR^4VPR^434K| VP 4VP4R# \ d9pTPPRT 24TP4Rp?LPRp?ii;i TP4i;i) uVСохранение высокодетализированной (Raw) историиNr$z<>
INSERT INTO usage_history
(client_id, bytes_received, bytes_sent, bytes_received_rate_mbps, bytes_sent_rate_mbps)
VALUES (?, ?, ?, ?, ?)
r%r&r<>r<>zError storing raw history: ) rWrYrr/rr0r2rr3r4r5)rr<>r7rrArBs&& r<00>store_usage_history<72>'OpenVPNDataGatherer.store_usage_history<72>s<><00><00><16> <12><13><EFBFBD><EFBFBD>-<2D>-<2D>/<2F><04><15><1B><1B><1D><06> <19>!<21><06><19>:<3A>:<3A>g<EFBFBD>&<26>&<26><1A>N<EFBFBD>N<EFBFBD>$<18>
<1F>w<EFBFBD><0F><1E>
<EFBFBD>
<EFBFBD>#7<><11>;<3B><1E>
<EFBFBD>
<EFBFBD>#3<>Q<EFBFBD>7<><1E>
<EFBFBD>
<EFBFBD>#=<3D>q<EFBFBD>A<><1E>
<EFBFBD>
<EFBFBD>#9<>1<EFBFBD>=<3D> <16>
<17>"<22> <11>K<EFBFBD>K<EFBFBD>M<EFBFBD>
<11>J<EFBFBD>J<EFBFBD>L<EFBFBD><4C> <19> <1C> <10>K<EFBFBD>K<EFBFBD> <1D> <1D> ;<3B>A<EFBFBD>3<EFBFBD>?<3F> @<40> <10>M<EFBFBD>M<EFBFBD>O<EFBFBD>O<EFBFBD><4F> <1C><> <11>J<EFBFBD>J<EFBFBD>L<EFBFBD>s0<00>C<00>A2C<00> D<03>#.D<03>D<00>D<03>D<00>D0c <0C>2<00>\P!4pVP4pVPV4pV'drRpVP'd!WP,
P 4pVP W44pVPV4VPPV4WnVP4VP8<>dCVPPR4VP4VP4Vn R#R#)u(Один цикл мониторингаg$@z%New day detected. Initiating cleanup.N)rr,r<>r<>rT<00> total_secondsr<73>r<>rZrCrUrVrr<>r<>)r<00> current_timer<65><00>clients_with_updatesr<73><00> clients_rateds& r<00>run_monitoring_cycle<6C>(OpenVPNDataGatherer.run_monitoring_cycle<6C>s<><00><00><1F>|<7C>|<7C>~<7E> <0C><1E>,<2C>,<2C>.<2E><0E> $<24>B<>B<>><3E>R<><1C> <1F><1C>I<EFBFBD><13>#<23>#<23>#<23>)<29>,@<40>,@<40>@<40>O<>O<>Q<> <09>!<21>0<>0<>1E<31>Q<>M<EFBFBD> <11> $<24> $<24>]<5D> 3<> <11> <1E> <1E> (<28> (<28><1D> 7<>+<2B><1C> <18> <1C> <1C> <1E><14>!7<>!7<> 7<> <10>K<EFBFBD>K<EFBFBD> <1C> <1C>D<> E<> <10> !<21> !<21> #<23>%1<>%6<>%6<>%8<>D<EFBFBD> "<22> 8rc <0C><><00>\VPRR^
44pVPPRV R24VPPR4VP 4\
P !V4K) \d TPPR4R#\d*pTPPRT 24Rp?R#Rp?ii;i) uЗапуск циклаrcrgz'Starting OpenVPN Monitoring. Interval: <20>szPress Ctrl+C to stopzMonitoring stopped by userzCritical error in main loop: N)
r<EFBFBD>r<>rr<>r<><00>time<6D>sleep<65>KeyboardInterruptr2r3)r<00>intervalrBs& r<00>start_monitoring<6E>$OpenVPNDataGatherer.start_monitoring<6E>s<><00><00><16>t<EFBFBD>,<2C>,<2C>-><3E>@P<>RT<52>U<>V<><08> <0C> <0B> <0B><18><18>B<>8<EFBFBD>*<2A>A<EFBFBD>N<>O<> <0C> <0B> <0B><18><18>/<2F>0<> C<01><16><14>)<29>)<29>+<2B><14>
<EFBFBD>
<EFBFBD>8<EFBFBD>$<24><> <20> ;<3B> <10>K<EFBFBD>K<EFBFBD> <1C> <1C>9<> :<3A><18> C<01> <10>K<EFBFBD>K<EFBFBD> <1D> <1D> =<3D>a<EFBFBD>S<EFBFBD>A<> B<> B<><42> C<01>s$<00>)B<00>&C<03>*C<03>3C<03>4C<03>C)rRrWrTrVrrZ)z
config.inir )r rErFrGrrQrSr<>r<>r<>r<>r<>r<>r<>rrHrIrJs@rrMrM`sK<00><><00><00>R<01> H<16>T6<>0<1B>$<19>L-<17>^k<1E>Z <17><19><9<>BC<01>CrrM<00>__main__)<0E>sqlite3r<33>r<>r<>r rr<00>dbrrrMr <00>gathererr<00>rr<00><module>r sY<00><01><0E> <0B> <09><13><0E>(<28><1E>S<19>S<19>lZC<01>ZC<01>x  <0C>z<EFBFBD><19>"<22>$<24>H<EFBFBD> <0C><1D><1D><1F>r