@@ -447,6 +447,141 @@ def extract_key_from_attr(attr_value: str) -> str:
447447 return False
448448
449449
450+ def diagnose_session () -> Dict [str , Any ]:
451+ """
452+ Diagnose the current session status and connectivity.
453+
454+ Returns:
455+ Dictionary containing diagnostic information about the session status.
456+ """
457+ diagnosis = {
458+ "sdk_initialized" : False ,
459+ "client_initialized" : False ,
460+ "has_api_key" : False ,
461+ "has_auth_token" : False ,
462+ "active_traces" : 0 ,
463+ "exporter_healthy" : False ,
464+ "export_stats" : {},
465+ "issues" : [],
466+ "recommendations" : []
467+ }
468+
469+ try :
470+ # Check SDK initialization
471+ diagnosis ["sdk_initialized" ] = tracer .initialized
472+ if not tracer .initialized :
473+ diagnosis ["issues" ].append ("AgentOps SDK not initialized" )
474+ diagnosis ["recommendations" ].append ("Call agentops.init() to initialize the SDK" )
475+ return diagnosis
476+
477+ # Check client
478+ client = get_client ()
479+ diagnosis ["client_initialized" ] = client .initialized
480+
481+ # Check API key
482+ diagnosis ["has_api_key" ] = bool (client .config .api_key )
483+ if not client .config .api_key :
484+ diagnosis ["issues" ].append ("No API key provided" )
485+ diagnosis ["recommendations" ].append ("Set AGENTOPS_API_KEY environment variable or pass api_key to init()" )
486+
487+ # Check auth token
488+ auth_token = client .get_current_jwt ()
489+ diagnosis ["has_auth_token" ] = bool (auth_token )
490+ if client .config .api_key and not auth_token :
491+ diagnosis ["issues" ].append ("Authentication failed - no JWT token available" )
492+ diagnosis ["recommendations" ].append ("Check if API key is valid and network connectivity is working" )
493+
494+ # Check active traces
495+ active_traces = tracer .get_active_traces ()
496+ diagnosis ["active_traces" ] = len (active_traces )
497+
498+ # Check exporter health
499+ try :
500+ # Access the exporter from the tracer's span processors
501+ span_processors = tracer ._provider ._active_span_processor ._span_processors
502+ for processor in span_processors :
503+ if hasattr (processor , '_exporter' ) and hasattr (processor ._exporter , 'is_healthy' ):
504+ diagnosis ["exporter_healthy" ] = processor ._exporter .is_healthy ()
505+ diagnosis ["export_stats" ] = processor ._exporter .get_export_stats ()
506+ break
507+ except Exception :
508+ pass
509+
510+ # Analyze issues
511+ if diagnosis ["export_stats" ].get ("failed_exports" , 0 ) > 0 :
512+ total_attempts = diagnosis ["export_stats" ].get ("total_attempts" , 0 )
513+ failed_exports = diagnosis ["export_stats" ].get ("failed_exports" , 0 )
514+ if total_attempts > 0 and failed_exports / total_attempts > 0.5 :
515+ diagnosis ["issues" ].append (f"High export failure rate: { failed_exports } /{ total_attempts } attempts failed" )
516+ diagnosis ["recommendations" ].append ("Check network connectivity and API key validity" )
517+
518+ if diagnosis ["has_api_key" ] and not diagnosis ["has_auth_token" ]:
519+ diagnosis ["issues" ].append ("API key provided but authentication failed" )
520+ diagnosis ["recommendations" ].append ("Verify API key is correct and check network connectivity" )
521+
522+ if not diagnosis ["issues" ]:
523+ diagnosis ["recommendations" ].append ("Session appears healthy - data should be reaching backend" )
524+
525+ except Exception as e :
526+ diagnosis ["issues" ].append (f"Error during diagnosis: { e } " )
527+
528+ return diagnosis
529+
530+
531+ def print_session_status ():
532+ """
533+ Print a user-friendly diagnostic report of the current session status.
534+ This is helpful for debugging when sessions aren't reaching the backend.
535+ """
536+ from termcolor import colored
537+
538+ diagnosis = diagnose_session ()
539+
540+ print ("\n " + "=" * 50 )
541+ print (colored ("AgentOps Session Diagnostic Report" , "cyan" , attrs = ["bold" ]))
542+ print ("=" * 50 )
543+
544+ # Status indicators
545+ status_items = [
546+ ("SDK Initialized" , diagnosis ["sdk_initialized" ]),
547+ ("Client Initialized" , diagnosis ["client_initialized" ]),
548+ ("API Key Present" , diagnosis ["has_api_key" ]),
549+ ("Authenticated" , diagnosis ["has_auth_token" ]),
550+ ("Exporter Healthy" , diagnosis ["exporter_healthy" ]),
551+ ]
552+
553+ print ("\n Status:" )
554+ for item , status in status_items :
555+ color = "green" if status else "red"
556+ symbol = "✓" if status else "✗"
557+ print (f" { colored (symbol , color )} { item } : { colored (str (status ), color )} " )
558+
559+ print (f"\n Active Traces: { diagnosis ['active_traces' ]} " )
560+
561+ # Export statistics
562+ if diagnosis ["export_stats" ]:
563+ stats = diagnosis ["export_stats" ]
564+ print (f"\n Export Statistics:" )
565+ print (f" Total Attempts: { stats .get ('total_attempts' , 0 )} " )
566+ print (f" Successful: { stats .get ('successful_exports' , 0 )} " )
567+ print (f" Failed: { stats .get ('failed_exports' , 0 )} " )
568+ print (f" Success Rate: { stats .get ('success_rate' , 0 )} %" )
569+
570+ # Issues
571+ if diagnosis ["issues" ]:
572+ print (colored ("\n Issues Found:" , "red" , attrs = ["bold" ]))
573+ for issue in diagnosis ["issues" ]:
574+ print (f" • { colored (issue , 'red' )} " )
575+
576+ # Recommendations
577+ if diagnosis ["recommendations" ]:
578+ print (colored ("\n Recommendations:" , "yellow" , attrs = ["bold" ]))
579+ for rec in diagnosis ["recommendations" ]:
580+ print (f" • { colored (rec , 'yellow' )} " )
581+
582+ print ("\n " + "=" * 50 )
583+
584+
450585__all__ = [
451586 # Legacy exports
452587 "start_session" ,
@@ -466,6 +601,9 @@ def extract_key_from_attr(attr_value: str) -> str:
466601 "update_trace_metadata" ,
467602 "Client" ,
468603 "get_client" ,
604+ # Diagnostics
605+ "diagnose_session" ,
606+ "print_session_status" ,
469607 # Decorators
470608 "trace" ,
471609 "session" ,
0 commit comments