eping 3.84__tar.gz → 3.86__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {eping-3.84 → eping-3.86}/PKG-INFO +7 -25
- {eping-3.84 → eping-3.86}/README.md +6 -24
- {eping-3.84 → eping-3.86}/pyproject.toml +1 -1
- {eping-3.84 → eping-3.86}/src/eping/eping.py +53 -6
- {eping-3.84 → eping-3.86}/src/eping.egg-info/PKG-INFO +7 -25
- {eping-3.84 → eping-3.86}/LICENSE +0 -0
- {eping-3.84 → eping-3.86}/setup.cfg +0 -0
- {eping-3.84 → eping-3.86}/src/eping/__init__.py +0 -0
- {eping-3.84 → eping-3.86}/src/eping/_launch_eping.py +0 -0
- {eping-3.84 → eping-3.86}/src/eping/epinga.py +0 -0
- {eping-3.84 → eping-3.86}/src/eping.egg-info/SOURCES.txt +0 -0
- {eping-3.84 → eping-3.86}/src/eping.egg-info/dependency_links.txt +0 -0
- {eping-3.84 → eping-3.86}/src/eping.egg-info/entry_points.txt +0 -0
- {eping-3.84 → eping-3.86}/src/eping.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: eping
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.86
|
|
4
4
|
Summary: Continuous ICMP reachability monitor built on fping, with a CSV logfile analyser (epinga)
|
|
5
5
|
Author-email: Ewald Jeitler <ewald@jeitler.cc>
|
|
6
6
|
License: GPL-3.0-or-later
|
|
@@ -17,7 +17,7 @@ Description-Content-Type: text/markdown
|
|
|
17
17
|
License-File: LICENSE
|
|
18
18
|
Dynamic: license-file
|
|
19
19
|
|
|
20
|
-
# eping.py 3.
|
|
20
|
+
# eping.py 3.86
|
|
21
21
|
|
|
22
22
|
Continuous ICMP reachability monitor built on `fping`. Scans a host list in a loop,
|
|
23
23
|
reports each host UP/DOWN/NO-DNS, counts state changes. CLI (curses) or web GUI.
|
|
@@ -40,14 +40,12 @@ Via pip (installs `eping` and `epinga` as commands, `fping` still required separ
|
|
|
40
40
|
pip install eping
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
Standalone scripts (installs/updates `eping.py`, `epinga.py
|
|
43
|
+
Standalone scripts (installs/updates `eping.py`, `epinga.py`):
|
|
44
44
|
|
|
45
45
|
```sh
|
|
46
46
|
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/ewaldj/eping/refs/heads/main/e-install.sh)"
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
`esplit.py` isn't part of the pip package - use the standalone install for it.
|
|
50
|
-
|
|
51
49
|
## Windows
|
|
52
50
|
|
|
53
51
|
Portable Windows version (web GUI only, no installation): download and unpack
|
|
@@ -149,7 +147,8 @@ named `*.txt` are never treated as CSV - they keep the plain host file format ab
|
|
|
149
147
|
- **Columns used**: `IP Address`, `Hostname`, `Serial Number`, `Model`, `Location`,
|
|
150
148
|
`sysLocation`, `Type`, `Comment`. All other columns are ignored.
|
|
151
149
|
- **Host entry**: the `Hostname` (default; rows without an IP are pinged by name too,
|
|
152
|
-
NO-DNS if it does not resolve). A name
|
|
150
|
+
NO-DNS if it does not resolve). A name without DNS record is pinged by the row's
|
|
151
|
+
IP instead (marked in the host popup, `-ncf` turns this off). A name that is not a valid hostname falls back to the
|
|
153
152
|
IP; rows without a usable entry are ignored. In the IP modes (`-ipo`, PREFER IP
|
|
154
153
|
ADDRESS, also when active while the file is added) the entry is the IP address
|
|
155
154
|
instead and rows without a valid IP are ignored. `-ph` is not needed for a CSV.
|
|
@@ -255,7 +254,7 @@ Single self-contained page, no external resources.
|
|
|
255
254
|
| Entry | Does |
|
|
256
255
|
|---|---|
|
|
257
256
|
| ADD HOSTS FILE FROM SERVER | picks one or more `.txt` files or inventory `.csv` files already on the server, adds their hosts; a `.csv` without the inventory header, e.g. an eping log, is refused |
|
|
258
|
-
| ADD HOSTS FILE FROM CLIENT |
|
|
257
|
+
| ADD HOSTS FILE FROM CLIENT | dialog with a file picker (`.txt`/`.csv`; works in Safari), adds the hosts; a file can also be dropped anywhere on the page |
|
|
259
258
|
| SAVE HOSTS FILE ON SERVER | confirmation, then saves the currently displayed hosts; blank name overwrites the active `-f` hostfile (first one, if eping.py was started with one) or, with none active, the default `eping-hosts.txt`; a typed name always saves as that new file instead, `.txt` appended once, active hostfile left untouched. If the displayed hosts carry inventory values (CSV import) an inventory `.csv` is written instead (`;` delimited, columns as in *Inventory CSV import*); a `.txt` name or hostfile then becomes `.csv`, the default is `eping-hosts.csv`. The options that differ from the default are written first as `opt:` lines (see *Host file format*); for a `.csv` the checkboxes `include options (opt: lines)` (default on) and `save as .txt (hosts only, no inventory)` (default off) are offered |
|
|
260
259
|
| UPLOAD FILE TO SERVER | picks a local `.txt`/`.csv`, saves as-is server-side, no host parsing; never overwrites, appends `-1`/`-2`/... |
|
|
261
260
|
| DOWNLOAD ALL HOSTS | full reference list: inventory `.csv` if the hosts carry inventory values, else `.txt`; non-default options first as `opt:` lines (`.csv`: checkboxes `include options`, default on, and `save as .txt`, default off) |
|
|
@@ -435,6 +434,7 @@ separated) · `-r` IP range (comma separated, shortened end)
|
|
|
435
434
|
| `-ipo` | — | off | start with IP ONLY |
|
|
436
435
|
| `-gn` | — | off | GET NAMES once at startup |
|
|
437
436
|
| `-ncs` | — | off | skip `--check-source` |
|
|
437
|
+
| `-ncf` | — | off | CSV: do not ping the CSV IP of a name without DNS record |
|
|
438
438
|
| `-up` | — | 0 | learning phase: after N rounds keep only hosts seen UP |
|
|
439
439
|
| `-setref` | — | off | with `-up`: hosts seen UP become new reference list |
|
|
440
440
|
|
|
@@ -728,21 +728,3 @@ Each bucket: Download (`<base>-<up|down|flap|nodns>-hosts.txt`) + Copy (clipboar
|
|
|
728
728
|
|
|
729
729
|
Row click expands: state-change history with timestamps, per-host stats (IP, uptime,
|
|
730
730
|
downtime, span, first/last seen, RTT min/avg/max).
|
|
731
|
-
|
|
732
|
-
# esplit.py 1.14
|
|
733
|
-
|
|
734
|
-
Splits a large CSV logfile into smaller parts by size.
|
|
735
|
-
|
|
736
|
-
```sh
|
|
737
|
-
./esplit.py # interactive menu
|
|
738
|
-
./esplit.py -i eping-log_2026-09-05.csv -o parts -s 20 # ~20MB parts
|
|
739
|
-
```
|
|
740
|
-
|
|
741
|
-
| Option | Effect |
|
|
742
|
-
|---|---|
|
|
743
|
-
| `-i`, `--input FILE` | CSV file to split (omit for interactive picker) |
|
|
744
|
-
| `-o`, `--output DIR` | output folder (created if missing) |
|
|
745
|
-
| `-s`, `--size MB` | max size per part |
|
|
746
|
-
|
|
747
|
-
Each part: `part_NNN.csv`, own header row. Rows never split across parts; a
|
|
748
|
-
`#COMMENT#` row lands in whichever part it falls into.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# eping.py 3.
|
|
1
|
+
# eping.py 3.86
|
|
2
2
|
|
|
3
3
|
Continuous ICMP reachability monitor built on `fping`. Scans a host list in a loop,
|
|
4
4
|
reports each host UP/DOWN/NO-DNS, counts state changes. CLI (curses) or web GUI.
|
|
@@ -21,14 +21,12 @@ Via pip (installs `eping` and `epinga` as commands, `fping` still required separ
|
|
|
21
21
|
pip install eping
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
Standalone scripts (installs/updates `eping.py`, `epinga.py
|
|
24
|
+
Standalone scripts (installs/updates `eping.py`, `epinga.py`):
|
|
25
25
|
|
|
26
26
|
```sh
|
|
27
27
|
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/ewaldj/eping/refs/heads/main/e-install.sh)"
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
`esplit.py` isn't part of the pip package - use the standalone install for it.
|
|
31
|
-
|
|
32
30
|
## Windows
|
|
33
31
|
|
|
34
32
|
Portable Windows version (web GUI only, no installation): download and unpack
|
|
@@ -130,7 +128,8 @@ named `*.txt` are never treated as CSV - they keep the plain host file format ab
|
|
|
130
128
|
- **Columns used**: `IP Address`, `Hostname`, `Serial Number`, `Model`, `Location`,
|
|
131
129
|
`sysLocation`, `Type`, `Comment`. All other columns are ignored.
|
|
132
130
|
- **Host entry**: the `Hostname` (default; rows without an IP are pinged by name too,
|
|
133
|
-
NO-DNS if it does not resolve). A name
|
|
131
|
+
NO-DNS if it does not resolve). A name without DNS record is pinged by the row's
|
|
132
|
+
IP instead (marked in the host popup, `-ncf` turns this off). A name that is not a valid hostname falls back to the
|
|
134
133
|
IP; rows without a usable entry are ignored. In the IP modes (`-ipo`, PREFER IP
|
|
135
134
|
ADDRESS, also when active while the file is added) the entry is the IP address
|
|
136
135
|
instead and rows without a valid IP are ignored. `-ph` is not needed for a CSV.
|
|
@@ -236,7 +235,7 @@ Single self-contained page, no external resources.
|
|
|
236
235
|
| Entry | Does |
|
|
237
236
|
|---|---|
|
|
238
237
|
| ADD HOSTS FILE FROM SERVER | picks one or more `.txt` files or inventory `.csv` files already on the server, adds their hosts; a `.csv` without the inventory header, e.g. an eping log, is refused |
|
|
239
|
-
| ADD HOSTS FILE FROM CLIENT |
|
|
238
|
+
| ADD HOSTS FILE FROM CLIENT | dialog with a file picker (`.txt`/`.csv`; works in Safari), adds the hosts; a file can also be dropped anywhere on the page |
|
|
240
239
|
| SAVE HOSTS FILE ON SERVER | confirmation, then saves the currently displayed hosts; blank name overwrites the active `-f` hostfile (first one, if eping.py was started with one) or, with none active, the default `eping-hosts.txt`; a typed name always saves as that new file instead, `.txt` appended once, active hostfile left untouched. If the displayed hosts carry inventory values (CSV import) an inventory `.csv` is written instead (`;` delimited, columns as in *Inventory CSV import*); a `.txt` name or hostfile then becomes `.csv`, the default is `eping-hosts.csv`. The options that differ from the default are written first as `opt:` lines (see *Host file format*); for a `.csv` the checkboxes `include options (opt: lines)` (default on) and `save as .txt (hosts only, no inventory)` (default off) are offered |
|
|
241
240
|
| UPLOAD FILE TO SERVER | picks a local `.txt`/`.csv`, saves as-is server-side, no host parsing; never overwrites, appends `-1`/`-2`/... |
|
|
242
241
|
| DOWNLOAD ALL HOSTS | full reference list: inventory `.csv` if the hosts carry inventory values, else `.txt`; non-default options first as `opt:` lines (`.csv`: checkboxes `include options`, default on, and `save as .txt`, default off) |
|
|
@@ -416,6 +415,7 @@ separated) · `-r` IP range (comma separated, shortened end)
|
|
|
416
415
|
| `-ipo` | — | off | start with IP ONLY |
|
|
417
416
|
| `-gn` | — | off | GET NAMES once at startup |
|
|
418
417
|
| `-ncs` | — | off | skip `--check-source` |
|
|
418
|
+
| `-ncf` | — | off | CSV: do not ping the CSV IP of a name without DNS record |
|
|
419
419
|
| `-up` | — | 0 | learning phase: after N rounds keep only hosts seen UP |
|
|
420
420
|
| `-setref` | — | off | with `-up`: hosts seen UP become new reference list |
|
|
421
421
|
|
|
@@ -709,21 +709,3 @@ Each bucket: Download (`<base>-<up|down|flap|nodns>-hosts.txt`) + Copy (clipboar
|
|
|
709
709
|
|
|
710
710
|
Row click expands: state-change history with timestamps, per-host stats (IP, uptime,
|
|
711
711
|
downtime, span, first/last seen, RTT min/avg/max).
|
|
712
|
-
|
|
713
|
-
# esplit.py 1.14
|
|
714
|
-
|
|
715
|
-
Splits a large CSV logfile into smaller parts by size.
|
|
716
|
-
|
|
717
|
-
```sh
|
|
718
|
-
./esplit.py # interactive menu
|
|
719
|
-
./esplit.py -i eping-log_2026-09-05.csv -o parts -s 20 # ~20MB parts
|
|
720
|
-
```
|
|
721
|
-
|
|
722
|
-
| Option | Effect |
|
|
723
|
-
|---|---|
|
|
724
|
-
| `-i`, `--input FILE` | CSV file to split (omit for interactive picker) |
|
|
725
|
-
| `-o`, `--output DIR` | output folder (created if missing) |
|
|
726
|
-
| `-s`, `--size MB` | max size per part |
|
|
727
|
-
|
|
728
|
-
Each part: `part_NNN.csv`, own header row. Rows never split across parts; a
|
|
729
|
-
`#COMMENT#` row lands in whichever part it falls into.
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "eping"
|
|
7
|
-
version = "3.
|
|
7
|
+
version = "3.86"
|
|
8
8
|
description = "Continuous ICMP reachability monitor built on fping, with a CSV logfile analyser (epinga)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "GPL-3.0-or-later" }
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# I knew how it worked.
|
|
8
8
|
# Now, only god knows it!
|
|
9
9
|
# - - - - - - - - - - - - - - - - - - - - - - - -
|
|
10
|
-
VERSION = '3.
|
|
10
|
+
VERSION = '3.86'
|
|
11
11
|
version = VERSION # legacy alias (kept for existing references)
|
|
12
12
|
|
|
13
13
|
# --- scaling limits ---
|
|
@@ -516,6 +516,8 @@ def create_sample_csv(filename=SAMPLE_CSV_NAME):
|
|
|
516
516
|
return False # a read-only directory must not stop eping
|
|
517
517
|
|
|
518
518
|
use_check_source = True # set from --no_check_source in main
|
|
519
|
+
csv_ip_fallback = True # set from --no_csv_fallback in main: a CSV hostname that does not resolve is pinged by its CSV IP
|
|
520
|
+
_csv_fb_names = frozenset() # hostnames pinged by their CSV IP in the last round (host popup)
|
|
519
521
|
web_readonly = False # True with --web_view: the CLI drives, the browser only looks
|
|
520
522
|
|
|
521
523
|
_fping_caps = None
|
|
@@ -902,14 +904,23 @@ def prepare_targets(hosts, ttl, progress_cb=None):
|
|
|
902
904
|
for n in pending:
|
|
903
905
|
resolve_name(n, ttl)
|
|
904
906
|
|
|
907
|
+
global _csv_fb_names
|
|
905
908
|
targets = []
|
|
906
909
|
name_map = {}
|
|
907
910
|
unresolved = []
|
|
911
|
+
fallback = set()
|
|
908
912
|
for h in hosts:
|
|
909
913
|
if is_ip_host(h):
|
|
910
914
|
target = h
|
|
911
915
|
else:
|
|
912
916
|
target = resolve_name(h, ttl)
|
|
917
|
+
if not target and csv_ip_fallback:
|
|
918
|
+
# no DNS record, but the inventory CSV has an address for this host: ping that
|
|
919
|
+
target = host_csv_ip.get(h) or ''
|
|
920
|
+
if target and is_ip_host(target):
|
|
921
|
+
fallback.add(h)
|
|
922
|
+
else:
|
|
923
|
+
target = ''
|
|
913
924
|
if not target:
|
|
914
925
|
unresolved.append(h)
|
|
915
926
|
continue
|
|
@@ -917,6 +928,7 @@ def prepare_targets(hosts, ttl, progress_cb=None):
|
|
|
917
928
|
name_map[target] = []
|
|
918
929
|
targets.append(target)
|
|
919
930
|
name_map[target].append(h)
|
|
931
|
+
_csv_fb_names = frozenset(fallback)
|
|
920
932
|
return targets, name_map, unresolved
|
|
921
933
|
|
|
922
934
|
|
|
@@ -2363,6 +2375,8 @@ def run_ping_round(active_hosts_list, threads_arg, rate_pps=DEFAULT_RATE_PPS,
|
|
|
2363
2375
|
scan_desc += (' (--rate %d not reachable, -i floor 1ms)' % rate_pps)
|
|
2364
2376
|
if use_check_source and '--check-source' in fping_capabilities():
|
|
2365
2377
|
scan_desc += ', check-source'
|
|
2378
|
+
if _csv_fb_names:
|
|
2379
|
+
scan_desc += ', %d by CSV IP (no DNS)' % len(_csv_fb_names)
|
|
2366
2380
|
if _scan_error:
|
|
2367
2381
|
scan_desc += ' | ERROR: ' + _scan_error
|
|
2368
2382
|
|
|
@@ -2834,6 +2848,16 @@ WEB_INDEX_HTML = r"""<!DOCTYPE html>
|
|
|
2834
2848
|
</div>
|
|
2835
2849
|
</div>
|
|
2836
2850
|
</div>
|
|
2851
|
+
<div id="addFromClientModal" class="modal-overlay" style="display:none">
|
|
2852
|
+
<div class="modal-box">
|
|
2853
|
+
<h3>ADD FROM CLIENT</h3>
|
|
2854
|
+
<p>Choose a `.txt` or `.csv` hosts file from this computer to add its hosts.</p>
|
|
2855
|
+
<input type="file" id="fileInputVis" accept=".txt,.csv,.list,text/plain" style="margin-bottom:14px;color:var(--fg)">
|
|
2856
|
+
<div class="modal-buttons">
|
|
2857
|
+
<button id="modalBtnAddFromClientCancel">CANCEL</button>
|
|
2858
|
+
</div>
|
|
2859
|
+
</div>
|
|
2860
|
+
</div>
|
|
2837
2861
|
<div id="chooseReportModal" class="modal-overlay" style="display:none">
|
|
2838
2862
|
<div class="modal-box wide xwide">
|
|
2839
2863
|
<h3>CHOOSE LOGFILE</h3>
|
|
@@ -4073,9 +4097,21 @@ document.getElementById('btnClear').onclick = function(){
|
|
|
4073
4097
|
|
|
4074
4098
|
/* ---- host file upload ---- */
|
|
4075
4099
|
var fileInput = document.getElementById('fileInput');
|
|
4100
|
+
var fileInputVis = document.getElementById('fileInputVis');
|
|
4101
|
+
var addFromClientModal = document.getElementById('addFromClientModal');
|
|
4102
|
+
function closeAddFromClient(){ addFromClientModal.style.display = 'none'; fileInputVis.value = ''; }
|
|
4103
|
+
function addFromClientOpen(){ return addFromClientModal.style.display === 'flex'; }
|
|
4104
|
+
document.getElementById('modalBtnAddFromClientCancel').onclick = closeAddFromClient;
|
|
4105
|
+
fileInputVis.addEventListener('change', function(){
|
|
4106
|
+
var f = fileInputVis.files && fileInputVis.files[0];
|
|
4107
|
+
closeAddFromClient();
|
|
4108
|
+
if(f) uploadHostsFile(f, null);
|
|
4109
|
+
});
|
|
4076
4110
|
fileInput.addEventListener('change', function(){
|
|
4077
4111
|
var f = fileInput.files && fileInput.files[0];
|
|
4078
|
-
if(
|
|
4112
|
+
if(f) uploadHostsFile(f, fileInput);
|
|
4113
|
+
});
|
|
4114
|
+
function uploadHostsFile(f, inp){
|
|
4079
4115
|
var rd = new FileReader();
|
|
4080
4116
|
rd.onload = function(){
|
|
4081
4117
|
note('uploading ' + f.name + ' ...', true);
|
|
@@ -4083,10 +4119,10 @@ fileInput.addEventListener('change', function(){
|
|
|
4083
4119
|
body: rd.result}).then(function(r){ return r.json(); }).then(function(j){
|
|
4084
4120
|
if(!j.ok){ note('upload failed: ' + (j.error||''), false); }
|
|
4085
4121
|
}).catch(function(){ note('upload failed', false); });
|
|
4086
|
-
|
|
4122
|
+
if(inp) inp.value = '';
|
|
4087
4123
|
};
|
|
4088
4124
|
rd.readAsText(f);
|
|
4089
|
-
}
|
|
4125
|
+
}
|
|
4090
4126
|
|
|
4091
4127
|
var uploadServerFileInput = document.getElementById('uploadServerFileInput');
|
|
4092
4128
|
uploadServerFileInput.addEventListener('change', function(){
|
|
@@ -4353,7 +4389,7 @@ document.getElementById('selDownload').onchange = function(){
|
|
|
4353
4389
|
this.value = ''; // reset - a select, not a toggle
|
|
4354
4390
|
if(!what) return;
|
|
4355
4391
|
if(what === 'add_from_server'){ openAddFromServer(); return; }
|
|
4356
|
-
if(what === 'add_from_client'){
|
|
4392
|
+
if(what === 'add_from_client'){ addFromClientModal.style.display = 'flex'; return; } // visible input: Safari blocks click() from select change
|
|
4357
4393
|
if(what === 'choose_logfile'){ openChooseLog(); return; }
|
|
4358
4394
|
if(what === 'delete_files'){ openDeleteFiles(); return; }
|
|
4359
4395
|
if(what === 'view_file'){ openViewFile(); return; }
|
|
@@ -4475,6 +4511,10 @@ document.addEventListener('keydown', function(e){
|
|
|
4475
4511
|
if(sk === 'y' || e.key === 'Enter'){ runSaveHostsFile(); e.preventDefault(); }
|
|
4476
4512
|
return;
|
|
4477
4513
|
}
|
|
4514
|
+
if(addFromClientOpen()){
|
|
4515
|
+
if(e.key === 'Escape'){ closeAddFromClient(); e.preventDefault(); }
|
|
4516
|
+
return;
|
|
4517
|
+
}
|
|
4478
4518
|
if(chooseLogOpen()){
|
|
4479
4519
|
if(e.key === 'Escape'){ closeChooseLog(); e.preventDefault(); }
|
|
4480
4520
|
return;
|
|
@@ -4698,6 +4738,7 @@ function tipRowsOf(d){
|
|
|
4698
4738
|
}
|
|
4699
4739
|
add('state', d.state, up ? 'up' : 'down');
|
|
4700
4740
|
if(d.changes > 0) add('previous', d.prev);
|
|
4741
|
+
if(d.dns_fb) add('dns', 'no DNS record - pinged by the CSV address', 'down');
|
|
4701
4742
|
if(d.ip && d.ip !== d.host) add('address', d.ip);
|
|
4702
4743
|
add('rtt (ms)', d.rtt && d.rtt.indexOf('-') !== 0 ? d.rtt : '');
|
|
4703
4744
|
add('last check', d.last_check);
|
|
@@ -5305,7 +5346,7 @@ _OPT_ARGS = None
|
|
|
5305
5346
|
_ARG_DEFAULTS = {}
|
|
5306
5347
|
# flag-less switches: dest -> flag
|
|
5307
5348
|
_OPT_SWITCHES = (('disable_versioncheck', '-du'), ('force_ipv4', '-4'), ('force_ipv6', '-6'),
|
|
5308
|
-
('diag', '-dg'), ('no_check_source', '-ncs'), ('web', '-web'),
|
|
5349
|
+
('diag', '-dg'), ('no_check_source', '-ncs'), ('no_csv_fallback', '-ncf'), ('web', '-web'),
|
|
5309
5350
|
('web_view', '-wv'), ('web_view_control', '-wvc'))
|
|
5310
5351
|
# ADV OPTIONS key -> argparse dest of its default
|
|
5311
5352
|
_OPT_KEY_DEST = {'backoff': 'backoff', 'timeout': 'timeout', 'retries': 'retries',
|
|
@@ -5986,6 +6027,7 @@ def host_details(name, tz_offset=0):
|
|
|
5986
6027
|
'prev': str(row[4]).strip() if row[4] else '', 'last_check': str(row[2]),
|
|
5987
6028
|
'rtt': str(row[3]), 'changes': row[5], 'change_ts': str(row[6] or ''),
|
|
5988
6029
|
'since_s': since, 'csv_ip': host_csv_ip.get(name, ''),
|
|
6030
|
+
'dns_fb': name in _csv_fb_names,
|
|
5989
6031
|
'csv_hostname': meta[0], 'serial': meta[1], 'model': meta[2],
|
|
5990
6032
|
'location': meta[3], 'sysloc': meta[4], 'type': meta[5], 'comment': meta[6],
|
|
5991
6033
|
'hist': hist_list(name, tz_offset)}
|
|
@@ -6319,6 +6361,8 @@ def build_cli_snapshot(args, backoff, timeout, retries, down_retries, flap_windo
|
|
|
6319
6361
|
parts.append('-lmf ' + str(args.log_max_files))
|
|
6320
6362
|
if args.no_check_source:
|
|
6321
6363
|
parts.append('-ncs')
|
|
6364
|
+
if args.no_csv_fallback:
|
|
6365
|
+
parts.append('-ncf')
|
|
6322
6366
|
if args.web:
|
|
6323
6367
|
parts.append('-web')
|
|
6324
6368
|
if args.web_view:
|
|
@@ -7053,6 +7097,7 @@ if __name__=='__main__':
|
|
|
7053
7097
|
parser.add_argument('-cf', '--confirm', default=str(CONFIRM_DEF), dest='confirm', help="consecutive DOWN observations before a host leaves UP (default: " + str(CONFIRM_DEF) + ", 1 = report every single observation)")
|
|
7054
7098
|
parser.add_argument('-ds', '--down_slices', default=str(DOWN_SLICES_DEF), dest='down_slices', help="spread the known DOWN hosts over N rounds, range 1-" + str(DOWN_SLICES_MAX) + " (default: " + str(DOWN_SLICES_DEF) + ", 1 = probe all of them every round)")
|
|
7055
7099
|
parser.add_argument('-fs', '--full_sweep', default=str(FULL_SWEEP_DEF), dest='full_sweep', help="every Nth run probes every host with full retries, range 0-" + str(FULL_SWEEP_MAX) + " (default: " + str(FULL_SWEEP_DEF) + ", 0 = disabled/never)")
|
|
7100
|
+
parser.add_argument('-ncf', '--no_csv_fallback', action="store_true", dest='no_csv_fallback', help="do not ping the CSV address of a host whose name does not resolve (default: it is pinged by the CSV IP and marked in the host popup)")
|
|
7056
7101
|
parser.add_argument('-ncs', '--no_check_source', action="store_true", dest='no_check_source', help="do not pass --check-source to fping (only needed for hosts replying from a different address)")
|
|
7057
7102
|
parser.add_argument('-web', '--web', action="store_true", dest='web', help="start the web gui instead of the terminal (CLI) output")
|
|
7058
7103
|
parser.add_argument('-wv', '--web_view', action="store_true", dest='web_view', help="CLI mode plus a read-only web view on --port (browser shows the same data, no controls)")
|
|
@@ -7095,6 +7140,7 @@ if __name__=='__main__':
|
|
|
7095
7140
|
retries = args.retries
|
|
7096
7141
|
interval = args.interval
|
|
7097
7142
|
use_check_source = not args.no_check_source
|
|
7143
|
+
csv_ip_fallback = not args.no_csv_fallback
|
|
7098
7144
|
dns_family = '4' if args.force_ipv4 else ('6' if args.force_ipv6 else 'auto')
|
|
7099
7145
|
|
|
7100
7146
|
# check online current version
|
|
@@ -7345,6 +7391,7 @@ if __name__=='__main__':
|
|
|
7345
7391
|
"# opt: -ds 4 # spread known DOWN hosts over N rounds\n",
|
|
7346
7392
|
"# opt: -fs 10 # every Nth run: full retries for everyone (0 = never)\n",
|
|
7347
7393
|
"# opt: -ncs # do not pass --check-source to fping\n",
|
|
7394
|
+
"# opt: -ncf # CSV: do not ping the CSV IP of a name without DNS record\n",
|
|
7348
7395
|
"# opt: -web # start the web gui instead of the CLI\n",
|
|
7349
7396
|
"# opt: -wv # CLI mode plus a read-only web view\n",
|
|
7350
7397
|
"# opt: -port 8080 # http port for -web / -wv\n",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: eping
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.86
|
|
4
4
|
Summary: Continuous ICMP reachability monitor built on fping, with a CSV logfile analyser (epinga)
|
|
5
5
|
Author-email: Ewald Jeitler <ewald@jeitler.cc>
|
|
6
6
|
License: GPL-3.0-or-later
|
|
@@ -17,7 +17,7 @@ Description-Content-Type: text/markdown
|
|
|
17
17
|
License-File: LICENSE
|
|
18
18
|
Dynamic: license-file
|
|
19
19
|
|
|
20
|
-
# eping.py 3.
|
|
20
|
+
# eping.py 3.86
|
|
21
21
|
|
|
22
22
|
Continuous ICMP reachability monitor built on `fping`. Scans a host list in a loop,
|
|
23
23
|
reports each host UP/DOWN/NO-DNS, counts state changes. CLI (curses) or web GUI.
|
|
@@ -40,14 +40,12 @@ Via pip (installs `eping` and `epinga` as commands, `fping` still required separ
|
|
|
40
40
|
pip install eping
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
Standalone scripts (installs/updates `eping.py`, `epinga.py
|
|
43
|
+
Standalone scripts (installs/updates `eping.py`, `epinga.py`):
|
|
44
44
|
|
|
45
45
|
```sh
|
|
46
46
|
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/ewaldj/eping/refs/heads/main/e-install.sh)"
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
`esplit.py` isn't part of the pip package - use the standalone install for it.
|
|
50
|
-
|
|
51
49
|
## Windows
|
|
52
50
|
|
|
53
51
|
Portable Windows version (web GUI only, no installation): download and unpack
|
|
@@ -149,7 +147,8 @@ named `*.txt` are never treated as CSV - they keep the plain host file format ab
|
|
|
149
147
|
- **Columns used**: `IP Address`, `Hostname`, `Serial Number`, `Model`, `Location`,
|
|
150
148
|
`sysLocation`, `Type`, `Comment`. All other columns are ignored.
|
|
151
149
|
- **Host entry**: the `Hostname` (default; rows without an IP are pinged by name too,
|
|
152
|
-
NO-DNS if it does not resolve). A name
|
|
150
|
+
NO-DNS if it does not resolve). A name without DNS record is pinged by the row's
|
|
151
|
+
IP instead (marked in the host popup, `-ncf` turns this off). A name that is not a valid hostname falls back to the
|
|
153
152
|
IP; rows without a usable entry are ignored. In the IP modes (`-ipo`, PREFER IP
|
|
154
153
|
ADDRESS, also when active while the file is added) the entry is the IP address
|
|
155
154
|
instead and rows without a valid IP are ignored. `-ph` is not needed for a CSV.
|
|
@@ -255,7 +254,7 @@ Single self-contained page, no external resources.
|
|
|
255
254
|
| Entry | Does |
|
|
256
255
|
|---|---|
|
|
257
256
|
| ADD HOSTS FILE FROM SERVER | picks one or more `.txt` files or inventory `.csv` files already on the server, adds their hosts; a `.csv` without the inventory header, e.g. an eping log, is refused |
|
|
258
|
-
| ADD HOSTS FILE FROM CLIENT |
|
|
257
|
+
| ADD HOSTS FILE FROM CLIENT | dialog with a file picker (`.txt`/`.csv`; works in Safari), adds the hosts; a file can also be dropped anywhere on the page |
|
|
259
258
|
| SAVE HOSTS FILE ON SERVER | confirmation, then saves the currently displayed hosts; blank name overwrites the active `-f` hostfile (first one, if eping.py was started with one) or, with none active, the default `eping-hosts.txt`; a typed name always saves as that new file instead, `.txt` appended once, active hostfile left untouched. If the displayed hosts carry inventory values (CSV import) an inventory `.csv` is written instead (`;` delimited, columns as in *Inventory CSV import*); a `.txt` name or hostfile then becomes `.csv`, the default is `eping-hosts.csv`. The options that differ from the default are written first as `opt:` lines (see *Host file format*); for a `.csv` the checkboxes `include options (opt: lines)` (default on) and `save as .txt (hosts only, no inventory)` (default off) are offered |
|
|
260
259
|
| UPLOAD FILE TO SERVER | picks a local `.txt`/`.csv`, saves as-is server-side, no host parsing; never overwrites, appends `-1`/`-2`/... |
|
|
261
260
|
| DOWNLOAD ALL HOSTS | full reference list: inventory `.csv` if the hosts carry inventory values, else `.txt`; non-default options first as `opt:` lines (`.csv`: checkboxes `include options`, default on, and `save as .txt`, default off) |
|
|
@@ -435,6 +434,7 @@ separated) · `-r` IP range (comma separated, shortened end)
|
|
|
435
434
|
| `-ipo` | — | off | start with IP ONLY |
|
|
436
435
|
| `-gn` | — | off | GET NAMES once at startup |
|
|
437
436
|
| `-ncs` | — | off | skip `--check-source` |
|
|
437
|
+
| `-ncf` | — | off | CSV: do not ping the CSV IP of a name without DNS record |
|
|
438
438
|
| `-up` | — | 0 | learning phase: after N rounds keep only hosts seen UP |
|
|
439
439
|
| `-setref` | — | off | with `-up`: hosts seen UP become new reference list |
|
|
440
440
|
|
|
@@ -728,21 +728,3 @@ Each bucket: Download (`<base>-<up|down|flap|nodns>-hosts.txt`) + Copy (clipboar
|
|
|
728
728
|
|
|
729
729
|
Row click expands: state-change history with timestamps, per-host stats (IP, uptime,
|
|
730
730
|
downtime, span, first/last seen, RTT min/avg/max).
|
|
731
|
-
|
|
732
|
-
# esplit.py 1.14
|
|
733
|
-
|
|
734
|
-
Splits a large CSV logfile into smaller parts by size.
|
|
735
|
-
|
|
736
|
-
```sh
|
|
737
|
-
./esplit.py # interactive menu
|
|
738
|
-
./esplit.py -i eping-log_2026-09-05.csv -o parts -s 20 # ~20MB parts
|
|
739
|
-
```
|
|
740
|
-
|
|
741
|
-
| Option | Effect |
|
|
742
|
-
|---|---|
|
|
743
|
-
| `-i`, `--input FILE` | CSV file to split (omit for interactive picker) |
|
|
744
|
-
| `-o`, `--output DIR` | output folder (created if missing) |
|
|
745
|
-
| `-s`, `--size MB` | max size per part |
|
|
746
|
-
|
|
747
|
-
Each part: `part_NNN.csv`, own header row. Rows never split across parts; a
|
|
748
|
-
`#COMMENT#` row lands in whichever part it falls into.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|