Skip to content

Commit 7c10eaa

Browse files
committed
getCCDBTimeMachineTimestamp.py: refactor printing of log messages
1 parent 0a24722 commit 7c10eaa

1 file changed

Lines changed: 55 additions & 42 deletions

File tree

‎GRID/utils/getCCDBTimeMachineTimestamp.py‎

Lines changed: 55 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,22 @@ def human(ts_ms):
9191
return datetime.fromtimestamp(ts_ms / 1000, tz=timezone.utc).strftime("%Y-%m-%d %H:%M:%S UTC")
9292

9393

94+
def print_log(severity, message, file):
95+
print(f"[getCCDBTimeMachineTimestamp] [{severity}] {message}", file=file)
96+
97+
98+
def print_info(message, file=sys.stderr):
99+
print_log("Info", message, file)
100+
101+
102+
def print_warning(message, file=sys.stderr):
103+
print_log("Warning", message, file)
104+
105+
106+
def print_error(message, file=sys.stderr):
107+
print_log("Error", message, file)
108+
109+
94110
def get_ccdb_objects(url, timeout = 15):
95111
req = urllib.request.Request(url, headers={"Accept": "application/json"})
96112
try:
@@ -120,15 +136,29 @@ def ccdb_cross_check(run, path, not_after, timeout=15):
120136

121137
objects = get_ccdb_objects(url)
122138
if not objects:
123-
return {**result, "error": "no CCDB object covers this instant"}
139+
result.update({"error": "no CCDB object covers this instant"})
124140

125141
as_of = [o for o in objects if o.get("Created", 0) <= not_after]
126142
newest = max(objects, key=lambda o: o.get("Created", 0))
127143
result.update({"newest": newest, "as_of": None, "outdated": False})
128144
if as_of:
129145
result["as_of"] = max(as_of, key=lambda o: o.get("Created", 0))
130146
result["outdated"] = newest["Created"] > result["as_of"]["Created"]
131-
return result
147+
148+
check_timestamp = f"/{result['timestamp']}" if result else ""
149+
if result is None or "error" in result:
150+
reason = result["error"] if result else "unknown error"
151+
print_warning(f"CCDB cross-check on {path}{check_timestamp} skipped: {reason}")
152+
elif result["as_of"] is None:
153+
print_info(f"CCDB cross-check on {path}{check_timestamp}: no object existed "
154+
f"yet at the recommended timestamp (newest is {describe_object(result['newest'])})")
155+
else:
156+
print_info(f"CCDB cross-check on {path}{check_timestamp}: as-of object is "
157+
f"{describe_object(result['as_of'])}")
158+
if result["outdated"]:
159+
print_info(f"CCDB's current object for this window is newer "
160+
f"({describe_object(result['newest'])}) - it postdates this pass's processing and "
161+
f"was not what this run actually saw.")
132162

133163

134164
def describe_object(o):
@@ -157,51 +187,36 @@ def get_NotAfter(year, period, run, passname, samples=9, ccdb_check_path="TPC/Ca
157187
int: CCDBTimeMachineTS NotAfter timestamp
158188
"""
159189
pass_dir = f"/alice/data/{year}/{period}/{run}/{passname}/"
160-
print(f"[getCCDBTimeMachineTimestamp] Looking for TF output under {pass_dir}", file=sys.stderr)
190+
print_info(f"Looking for TF output under {pass_dir}")
161191

162192
matches = find_tf_output_files(pass_dir, run)
163193
if not matches:
164-
sys.exit(f"[getCCDBTimeMachineTimestamp] No o2_ctf_run{int(run):08d}_orbit* output found "
165-
f"under {pass_dir}. Check year/period/run/pass, or this run+pass may not use this "
166-
f"catalog layout. Refusing to guess a timestamp.")
194+
print_error(f"No o2_ctf_run{int(run):08d}_orbit* output found under {pass_dir}. "
195+
f"Check year/period/run/pass, or this run+pass may not use this "
196+
f"catalog layout. Refusing to guess a timestamp. Exiting...")
197+
sys.exit(1)
167198

168199
sampled = sample_evenly(matches, samples)
169200
ctimes = []
170201
for lfn in sampled:
171202
ctime = stat_ctime(lfn)
172203
if ctime is not None:
173204
ctimes.append(ctime)
174-
print(f"[getCCDBTimeMachineTimestamp] {human(ctime)} {lfn}", file=sys.stderr)
205+
print_info(f"{human(ctime)} {lfn}")
175206

176207
if len(ctimes) < 2:
177-
sys.exit(f"[getCCDBTimeMachineTimestamp] Only got {len(ctimes)} usable timestamp(s) out of "
178-
f"{len(sampled)} sampled files ({len(matches)} found in total); refusing to guess.")
208+
print_error(f"Only got {len(ctimes)} usable timestamp(s) out of {len(sampled)} "
209+
f"sampled files ({len(matches)} found in total); refusing to guess. Exiting...")
210+
sys.exit(1)
179211

180212
not_after = int(statistics.median(ctimes))
181213
spread_h = (max(ctimes) - min(ctimes)) / 3.6e6
182-
print(f"[getCCDBTimeMachineTimestamp] {len(ctimes)} samples out of {len(matches)} TF outputs found; "
183-
f"span {human(min(ctimes))} .. {human(max(ctimes))} ({spread_h:.1f} h)", file=sys.stderr)
184-
print(f"[getCCDBTimeMachineTimestamp] Recommended NotAfter: {not_after} ({human(not_after)})",
185-
file=sys.stderr)
214+
print_info(f"{len(ctimes)} samples out of {len(matches)} TF outputs found; "
215+
f"span {human(min(ctimes))} .. {human(max(ctimes))} ({spread_h:.1f} h)")
216+
print_info(f"Recommended NotAfter: {not_after} ({human(not_after)})")
186217

187218
if ccdb_check:
188-
check = ccdb_cross_check(run, ccdb_check_path, not_after)
189-
check_timestamp = f"/{check['timestamp']}" if check else ""
190-
if check is None or "error" in check:
191-
reason = check["error"] if check else "unknown error"
192-
print(f"[getCCDBTimeMachineTimestamp] CCDB cross-check on {ccdb_check_path}{check_timestamp} skipped: {reason}",
193-
file=sys.stderr)
194-
elif check["as_of"] is None:
195-
print(f"[getCCDBTimeMachineTimestamp] CCDB cross-check on {ccdb_check_path}{check_timestamp}: no object "
196-
f"existed yet at the recommended timestamp (earliest is {describe_object(check['newest'])})",
197-
file=sys.stderr)
198-
else:
199-
print(f"[getCCDBTimeMachineTimestamp] CCDB cross-check on {ccdb_check_path}{check_timestamp}: as-of object is "
200-
f"{describe_object(check['as_of'])}", file=sys.stderr)
201-
if check["outdated"]:
202-
print(f"[getCCDBTimeMachineTimestamp] note: CCDB's current object for this window is newer "
203-
f"({describe_object(check['newest'])}) - it postdates this pass's processing and was "
204-
f"not what this run actually saw.", file=sys.stderr)
219+
ccdb_cross_check(run, ccdb_check_path, not_after)
205220

206221
return not_after
207222

@@ -221,7 +236,7 @@ def query_CCDBTimeMachineTS(base_url, user, period, passname):
221236
user_path = 'Users/' + user[0] + '/' + user
222237
url = f"{base_url}/browse/{user_path}/CCDBTimeMachineTS/{query}"
223238

224-
print(f"[getCCDBTimeMachineTimestamp] Checking if CCDBTimeMachineTS already exists: {url}", file=sys.stderr)
239+
print_info(f"Checking if CCDBTimeMachineTS already exists: {url}")
225240

226241
response = requests.get(url, cert=(cert_path, key_path), verify=False)
227242
if response.status_code == 200:
@@ -232,9 +247,9 @@ def filter_known_fields(cls, data: dict) -> dict:
232247
return {k: v for k, v in data.items() if k in valid_keys}
233248

234249
clean_meta = filter_known_fields(CCDBTimeMachineTS, meta[0])
235-
print(f"[getCCDBTimeMachineTimestamp] Found object for {clean_meta['Period']}, Pass: {clean_meta['Pass']}, "
236-
f"NotAfter: {clean_meta['NotAfter']} ({human(clean_meta['NotAfter'])}), uploaded by LPMProductionTag {clean_meta['LPMProductionTag']}",
237-
file=sys.stderr)
250+
print_info(f"Found object for {clean_meta['Period']}, Pass: {clean_meta['Pass']}, "
251+
f"NotAfter: {clean_meta['NotAfter']} ({human(clean_meta['NotAfter'])}), "
252+
f"uploaded by LPMProductionTag {clean_meta['LPMProductionTag']}")
238253
return clean_meta['NotAfter'], True
239254

240255
return None, False
@@ -262,7 +277,7 @@ def upload_CCDBTimeMachineTS(base_url, user, keys):
262277
stop = start + 1
263278
url = f"{base_url}/{user_path}/CCDBTimeMachineTS/{start}/{stop}/{query}"
264279

265-
print(f"[getCCDBTimeMachineTimestamp] Uploading CCDBTimeMachineTS: {url}", file=sys.stderr)
280+
print_info(f"Uploading CCDBTimeMachineTS: {url}")
266281

267282
# Prepare request
268283
with open(empty_file, 'rb') as f:
@@ -272,7 +287,7 @@ def upload_CCDBTimeMachineTS(base_url, user, keys):
272287
os.remove(empty_file)
273288

274289
if response.status_code != 201:
275-
print(f"[getCCDBTimeMachineTimestamp] Upload failed, response: {response.status_code}", file=sys.stderr)
290+
print_warning(f"Upload failed, response: {response.status_code}")
276291

277292

278293
def get_CCDBTimeMachineTS(production_tag, year, period, run, passname,
@@ -293,22 +308,20 @@ def get_CCDBTimeMachineTS(production_tag, year, period, run, passname,
293308
not_after, found = query_CCDBTimeMachineTS(ccdb_url, username, period, passname)
294309

295310
if not found or force_overwrite:
296-
print("[getCCDBTimeMachineTimestamp] Estimating CCDBTimeMachineTS for "
297-
f"LPMProductionTag: {production_tag}, Period: {period}, Pass: {passname}", file=sys.stderr)
311+
print_info("Estimating CCDBTimeMachineTS for "
312+
f"LPMProductionTag: {production_tag}, Period: {period}, Pass: {passname}")
298313
not_after = get_NotAfter(year, period, run, passname, samples, ccdb_check_path, ccdb_check)
299314

300315
if publish_to_ccdb:
301316
if skip_ccdb_query:
302-
print("[getCCDBTimeMachineTimestamp] CCDB query was skipped, a newer object may be "
303-
"uploaded on top of an existing one", file=sys.stderr)
317+
print_info("CCDB query was skipped, a newer object may be uploaded on top of an existing one")
304318
elif not found:
305319
# check again in case another subjob uploaded an object in the meantime
306320
not_after_q, found = query_CCDBTimeMachineTS(ccdb_url, username, period, passname)
307321

308322
if found:
309323
if force_overwrite:
310-
print("[getCCDBTimeMachineTimestamp] Forcing upload of a newer object "
311-
"on top of the existing one", file=sys.stderr)
324+
print_info("Forcing upload of a newer object on top of the existing one")
312325
else:
313326
return not_after_q
314327

0 commit comments

Comments
 (0)