@@ -993,6 +993,94 @@ def _seed_connection_monitor_data(self, now):
993993
994994 log .info ("Demo: seeded %d connection monitor samples (%d days, 3 targets)" , len (rows ), days )
995995
996+ # --- Seed traceroute traces ---
997+ self ._seed_traceroute_traces (cm , cf_id , gg_id , now , rng )
998+
999+ def _seed_traceroute_traces (self , cm , cf_id , gg_id , now , rng ):
1000+ """Seed realistic traceroute traces for demo targets."""
1001+ import hashlib
1002+
1003+ # Realistic hop templates: home -> ISP -> backbone -> target
1004+ hop_templates = {
1005+ cf_id : [
1006+ {"hop_ip" : "192.168.178.1" , "hop_host" : "fritz.box" , "base_lat" : 1.2 },
1007+ {"hop_ip" : "62.155.243.1" , "hop_host" : "dslam-ffm.telekom.de" , "base_lat" : 5.8 },
1008+ {"hop_ip" : "62.157.250.22" , "hop_host" : "cr-ffm01.telekom.de" , "base_lat" : 8.1 },
1009+ {"hop_ip" : "62.157.250.89" , "hop_host" : "cr-ffm02.telekom.de" , "base_lat" : 8.9 },
1010+ {"hop_ip" : "80.156.160.178" , "hop_host" : "decix-peer.telekom.de" , "base_lat" : 10.3 },
1011+ {"hop_ip" : "172.71.128.2" , "hop_host" : "cloudflare-ic.decix.net" , "base_lat" : 11.0 },
1012+ {"hop_ip" : "172.71.128.34" , "hop_host" : None , "base_lat" : 11.5 },
1013+ {"hop_ip" : "104.16.132.229" , "hop_host" : "one.one.one.one" , "base_lat" : 11.8 },
1014+ {"hop_ip" : None , "hop_host" : None , "base_lat" : None }, # timeout hop
1015+ {"hop_ip" : "172.71.0.150" , "hop_host" : None , "base_lat" : 12.1 },
1016+ {"hop_ip" : "1.1.1.1" , "hop_host" : "one.one.one.one" , "base_lat" : 12.4 },
1017+ ],
1018+ gg_id : [
1019+ {"hop_ip" : "192.168.178.1" , "hop_host" : "fritz.box" , "base_lat" : 1.1 },
1020+ {"hop_ip" : "62.155.243.1" , "hop_host" : "dslam-ffm.telekom.de" , "base_lat" : 5.6 },
1021+ {"hop_ip" : "62.157.250.22" , "hop_host" : "cr-ffm01.telekom.de" , "base_lat" : 8.0 },
1022+ {"hop_ip" : "62.157.250.89" , "hop_host" : "cr-ffm02.telekom.de" , "base_lat" : 8.7 },
1023+ {"hop_ip" : "80.156.160.178" , "hop_host" : "decix-peer.telekom.de" , "base_lat" : 10.1 },
1024+ {"hop_ip" : "209.85.149.32" , "hop_host" : "google-ic.decix.net" , "base_lat" : 11.2 },
1025+ {"hop_ip" : "108.170.236.57" , "hop_host" : None , "base_lat" : 12.0 },
1026+ {"hop_ip" : "142.251.51.15" , "hop_host" : None , "base_lat" : 13.1 },
1027+ {"hop_ip" : None , "hop_host" : None , "base_lat" : None }, # timeout hop
1028+ {"hop_ip" : "108.170.232.97" , "hop_host" : None , "base_lat" : 13.8 },
1029+ {"hop_ip" : "142.250.236.131" , "hop_host" : None , "base_lat" : 14.2 },
1030+ {"hop_ip" : "8.8.8.8" , "hop_host" : "dns.google" , "base_lat" : 14.5 },
1031+ ],
1032+ }
1033+
1034+ trace_configs = [
1035+ {"target_id" : cf_id , "days_ago" : 5 , "trigger" : "outage" , "reached" : True },
1036+ {"target_id" : cf_id , "days_ago" : 2 , "trigger" : "packet_loss" , "reached" : True },
1037+ {"target_id" : cf_id , "days_ago" : 0 , "trigger" : "manual" , "reached" : True },
1038+ {"target_id" : gg_id , "days_ago" : 4 , "trigger" : "outage" , "reached" : True },
1039+ {"target_id" : gg_id , "days_ago" : 1 , "trigger" : "manual" , "reached" : True },
1040+ ]
1041+
1042+ for tc in trace_configs :
1043+ template = hop_templates [tc ["target_id" ]]
1044+ hops = []
1045+ ips_for_fp = []
1046+ for i , tmpl in enumerate (template ):
1047+ if tmpl ["base_lat" ] is None :
1048+ # Timeout hop
1049+ hops .append ({
1050+ "hop_index" : i + 1 ,
1051+ "hop_ip" : None ,
1052+ "hop_host" : None ,
1053+ "latency_ms" : None ,
1054+ "probes_responded" : 0 ,
1055+ })
1056+ ips_for_fp .append ("*" )
1057+ else :
1058+ lat = round (tmpl ["base_lat" ] + rng .uniform (- 0.5 , 0.5 ), 2 )
1059+ probes = 3 if rng .random () > 0.05 else rng .randint (1 , 2 )
1060+ hops .append ({
1061+ "hop_index" : i + 1 ,
1062+ "hop_ip" : tmpl ["hop_ip" ],
1063+ "hop_host" : tmpl ["hop_host" ],
1064+ "latency_ms" : lat ,
1065+ "probes_responded" : probes ,
1066+ })
1067+ ips_for_fp .append (tmpl ["hop_ip" ] or "*" )
1068+
1069+ fp = hashlib .md5 (">" .join (ips_for_fp ).encode ()).hexdigest ()[:16 ]
1070+ ts = (now - timedelta (days = tc ["days_ago" ], hours = rng .randint (0 , 12 ))).timestamp ()
1071+
1072+ cm .save_trace (
1073+ target_id = tc ["target_id" ],
1074+ timestamp = ts ,
1075+ trigger_reason = tc ["trigger" ],
1076+ hops = hops ,
1077+ route_fingerprint = fp ,
1078+ reached_target = tc ["reached" ],
1079+ is_demo = True ,
1080+ )
1081+
1082+ log .info ("Demo: seeded %d traceroute traces" , len (trace_configs ))
1083+
9961084 @staticmethod
9971085 def _generate_bqm_png (width = 800 , height = 200 , seed = 0 ):
9981086 """Generate a simple BQM-style quality graph as PNG bytes."""
0 commit comments