eping 3.84__tar.gz → 3.85__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eping
3
- Version: 3.84
3
+ Version: 3.85
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.84
20
+ # eping.py 3.85
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`, `esplit.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 that is not a valid hostname falls back to the
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.
@@ -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.84
1
+ # eping.py 3.85
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`, `esplit.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 that is not a valid hostname falls back to the
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.
@@ -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.84"
7
+ version = "3.85"
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.84'
10
+ VERSION = '3.85'
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
 
@@ -4698,6 +4712,7 @@ function tipRowsOf(d){
4698
4712
  }
4699
4713
  add('state', d.state, up ? 'up' : 'down');
4700
4714
  if(d.changes > 0) add('previous', d.prev);
4715
+ if(d.dns_fb) add('dns', 'no DNS record - pinged by the CSV address', 'down');
4701
4716
  if(d.ip && d.ip !== d.host) add('address', d.ip);
4702
4717
  add('rtt (ms)', d.rtt && d.rtt.indexOf('-') !== 0 ? d.rtt : '');
4703
4718
  add('last check', d.last_check);
@@ -5305,7 +5320,7 @@ _OPT_ARGS = None
5305
5320
  _ARG_DEFAULTS = {}
5306
5321
  # flag-less switches: dest -> flag
5307
5322
  _OPT_SWITCHES = (('disable_versioncheck', '-du'), ('force_ipv4', '-4'), ('force_ipv6', '-6'),
5308
- ('diag', '-dg'), ('no_check_source', '-ncs'), ('web', '-web'),
5323
+ ('diag', '-dg'), ('no_check_source', '-ncs'), ('no_csv_fallback', '-ncf'), ('web', '-web'),
5309
5324
  ('web_view', '-wv'), ('web_view_control', '-wvc'))
5310
5325
  # ADV OPTIONS key -> argparse dest of its default
5311
5326
  _OPT_KEY_DEST = {'backoff': 'backoff', 'timeout': 'timeout', 'retries': 'retries',
@@ -5986,6 +6001,7 @@ def host_details(name, tz_offset=0):
5986
6001
  'prev': str(row[4]).strip() if row[4] else '', 'last_check': str(row[2]),
5987
6002
  'rtt': str(row[3]), 'changes': row[5], 'change_ts': str(row[6] or ''),
5988
6003
  'since_s': since, 'csv_ip': host_csv_ip.get(name, ''),
6004
+ 'dns_fb': name in _csv_fb_names,
5989
6005
  'csv_hostname': meta[0], 'serial': meta[1], 'model': meta[2],
5990
6006
  'location': meta[3], 'sysloc': meta[4], 'type': meta[5], 'comment': meta[6],
5991
6007
  'hist': hist_list(name, tz_offset)}
@@ -6319,6 +6335,8 @@ def build_cli_snapshot(args, backoff, timeout, retries, down_retries, flap_windo
6319
6335
  parts.append('-lmf ' + str(args.log_max_files))
6320
6336
  if args.no_check_source:
6321
6337
  parts.append('-ncs')
6338
+ if args.no_csv_fallback:
6339
+ parts.append('-ncf')
6322
6340
  if args.web:
6323
6341
  parts.append('-web')
6324
6342
  if args.web_view:
@@ -7053,6 +7071,7 @@ if __name__=='__main__':
7053
7071
  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
7072
  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
7073
  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)")
7074
+ 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
7075
  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
7076
  parser.add_argument('-web', '--web', action="store_true", dest='web', help="start the web gui instead of the terminal (CLI) output")
7058
7077
  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 +7114,7 @@ if __name__=='__main__':
7095
7114
  retries = args.retries
7096
7115
  interval = args.interval
7097
7116
  use_check_source = not args.no_check_source
7117
+ csv_ip_fallback = not args.no_csv_fallback
7098
7118
  dns_family = '4' if args.force_ipv4 else ('6' if args.force_ipv6 else 'auto')
7099
7119
 
7100
7120
  # check online current version
@@ -7345,6 +7365,7 @@ if __name__=='__main__':
7345
7365
  "# opt: -ds 4 # spread known DOWN hosts over N rounds\n",
7346
7366
  "# opt: -fs 10 # every Nth run: full retries for everyone (0 = never)\n",
7347
7367
  "# opt: -ncs # do not pass --check-source to fping\n",
7368
+ "# opt: -ncf # CSV: do not ping the CSV IP of a name without DNS record\n",
7348
7369
  "# opt: -web # start the web gui instead of the CLI\n",
7349
7370
  "# opt: -wv # CLI mode plus a read-only web view\n",
7350
7371
  "# 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.84
3
+ Version: 3.85
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.84
20
+ # eping.py 3.85
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`, `esplit.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 that is not a valid hostname falls back to the
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.
@@ -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