@@ -530,7 +530,13 @@ impl ClusterDiscovery {
530
530
}
531
531
532
532
#[ async_backtrace:: framed]
533
- pub async fn unregister_to_metastore ( self : & Arc < Self > , signal : & mut SignalStream ) {
533
+ pub async fn unregister_to_metastore (
534
+ self : & Arc < Self > ,
535
+ signal : & mut SignalStream ,
536
+ cfg : & InnerConfig ,
537
+ ) {
538
+ self . report_telemetry_data ( cfg, None ) . await ;
539
+
534
540
let mut heartbeat = self . heartbeat . lock ( ) . await ;
535
541
536
542
if let Err ( shutdown_failure) = heartbeat. shutdown ( ) . await {
@@ -646,8 +652,7 @@ impl ClusterDiscovery {
646
652
match self . warehouse_manager . start_node ( node_info. clone ( ) ) . await {
647
653
Ok ( seq_node) => {
648
654
self . start_heartbeat ( seq_node) . await ?;
649
- self . report_telemetry_data ( & node_info, cfg, online_nodes)
650
- . await ;
655
+ self . report_telemetry_data ( cfg, Some ( online_nodes) ) . await ;
651
656
Ok ( ( ) )
652
657
}
653
658
Err ( cause) => Err ( cause. add_message_back ( "(while cluster api add_node)." ) ) ,
@@ -688,43 +693,138 @@ impl ClusterDiscovery {
688
693
Ok ( settings. get_enterprise_license ( ) )
689
694
}
690
695
691
- async fn report_telemetry_data (
692
- & self ,
693
- _node_info : & NodeInfo ,
694
- cfg : & InnerConfig ,
695
- online_nodes : Vec < NodeInfo > ,
696
- ) {
697
- if let Ok ( key) = Self :: get_license_key ( & self . tenant_id ) . await {
698
- if !key. is_empty ( ) {
699
- if let Ok ( claims) = LicenseManagerSwitch :: instance ( ) . parse_license ( & key) {
700
- let license_type = claims. custom . r#type . as_deref ( ) . unwrap_or ( "" ) . to_lowercase ( ) ;
701
- if license_type != "trial" && !cfg. telemetry . enabled {
702
- return ;
703
- }
704
- }
696
+ async fn report_telemetry_data ( & self , cfg : & InnerConfig , online_nodes : Option < Vec < NodeInfo > > ) {
697
+ let start_time = std:: time:: Instant :: now ( ) ;
698
+
699
+ let license_result = Self :: get_license_key ( & self . tenant_id )
700
+ . await
701
+ . ok ( )
702
+ . filter ( |key| !key. is_empty ( ) )
703
+ . and_then ( |key| LicenseManagerSwitch :: instance ( ) . parse_license ( & key) . ok ( ) ) ;
704
+
705
+ if let Some ( ref claims) = license_result {
706
+ let license_type = claims. custom . r#type . as_deref ( ) . unwrap_or ( "" ) . to_lowercase ( ) ;
707
+ if license_type != "trial" && !cfg. telemetry . enabled {
708
+ return ;
705
709
}
706
710
}
707
711
712
+ let license_info = match license_result {
713
+ Some ( claims) => {
714
+ let expires_at = claims. expires_at . map ( |d| d. as_secs ( ) ) . unwrap_or ( 0 ) ;
715
+ serde_json:: json!( {
716
+ "has_license" : true ,
717
+ "expires_at" : expires_at,
718
+ "license_info" : claims. custom
719
+ } )
720
+ }
721
+ None => serde_json:: json!( {
722
+ "has_license" : false ,
723
+ "license_info" : null
724
+ } ) ,
725
+ } ;
726
+
727
+ // Collect system information
728
+ let mut system = sysinfo:: System :: new ( ) ;
729
+ system. refresh_memory ( ) ;
730
+ system. refresh_cpu_all ( ) ;
731
+
732
+ let event_type = if online_nodes. is_none ( ) {
733
+ "node_shutdown"
734
+ } else {
735
+ "node_startup"
736
+ } ;
737
+
708
738
let payload = serde_json:: json!( {
709
739
"timestamp" : std:: time:: SystemTime :: now( )
710
740
. duration_since( std:: time:: UNIX_EPOCH )
711
741
. map( |d| d. as_secs( ) )
712
742
. unwrap_or( 0 ) ,
713
- "cluster_id" : self . cluster_id,
714
- "node_id" : self . local_id,
715
- "tenant_name" : self . tenant_id,
716
- "version" : DATABEND_COMMIT_VERSION . as_str( ) ,
717
- "cpu_cores" : num_cpus:: get( ) ,
718
- "storage_info" : cfg. storage. params. to_string( ) ,
719
- "nodes" : online_nodes. iter( ) . map( |node| serde_json:: json!( {
720
- "id" : node. id,
721
- "secret" : node. secret,
722
- "cpu_nums" : node. cpu_nums,
723
- "version" : node. version,
724
- "binary_version" : node. binary_version,
725
- "cluster_id" : node. cluster_id,
726
- "warehouse_id" : node. warehouse_id,
727
- } ) ) . collect:: <Vec <_>>( ) ,
743
+ "event_type" : event_type,
744
+ "cluster" : {
745
+ "cluster_id" : self . cluster_id,
746
+ "tenant_name" : self . tenant_id
747
+ } ,
748
+ "node" : {
749
+ "node_id" : self . local_id,
750
+ "version" : DATABEND_COMMIT_VERSION . as_str( )
751
+ } ,
752
+ "system" : {
753
+ "os_name" : sysinfo:: System :: name( ) . unwrap_or_else( || "unknown" . to_string( ) ) ,
754
+ "os_version" : sysinfo:: System :: os_version( ) . unwrap_or_else( || "unknown" . to_string( ) ) ,
755
+ "kernel_version" : sysinfo:: System :: kernel_version( ) . unwrap_or_else( || "unknown" . to_string( ) ) ,
756
+ "arch" : sysinfo:: System :: cpu_arch( ) ,
757
+ "cpu_cores" : system. cpus( ) . len( ) ,
758
+ "total_memory" : system. total_memory( ) ,
759
+ "available_memory" : system. available_memory( ) ,
760
+ "used_memory" : system. used_memory( ) ,
761
+ "uptime_seconds" : sysinfo:: System :: uptime( )
762
+ } ,
763
+ "cache_strategy" : {
764
+ "enable_table_meta_cache" : cfg. cache. enable_table_meta_cache,
765
+ "table_meta_snapshot_count" : cfg. cache. table_meta_snapshot_count,
766
+ "table_meta_segment_bytes" : cfg. cache. table_meta_segment_bytes,
767
+ "block_meta_count" : cfg. cache. block_meta_count,
768
+ "segment_block_metas_count" : cfg. cache. segment_block_metas_count,
769
+ "table_meta_statistic_count" : cfg. cache. table_meta_statistic_count,
770
+ "segment_statistics_count" : cfg. cache. segment_statistics_count,
771
+ "enable_table_index_bloom" : cfg. cache. enable_table_index_bloom,
772
+ "table_bloom_index_meta_count" : cfg. cache. table_bloom_index_meta_count,
773
+ "table_bloom_index_filter_count" : cfg. cache. table_bloom_index_filter_count,
774
+ "table_bloom_index_filter_size" : cfg. cache. table_bloom_index_filter_size,
775
+ "table_prune_partitions_count" : cfg. cache. table_prune_partitions_count,
776
+ "inverted_index_meta_count" : cfg. cache. inverted_index_meta_count,
777
+ "inverted_index_filter_size" : cfg. cache. inverted_index_filter_size,
778
+ "vector_index_meta_count" : cfg. cache. vector_index_meta_count,
779
+ "vector_index_filter_size" : cfg. cache. vector_index_filter_size,
780
+ "data_cache_in_memory_bytes" : cfg. cache. data_cache_in_memory_bytes,
781
+ "table_data_cache_population_queue_size" : cfg. cache. table_data_cache_population_queue_size,
782
+ "table_data_deserialized_data_bytes" : cfg. cache. table_data_deserialized_data_bytes,
783
+ "disk_cache_max_bytes" : cfg. cache. disk_cache_config. max_bytes,
784
+ "disk_cache_sync_data" : cfg. cache. disk_cache_config. sync_data
785
+ } ,
786
+ "memory_management" : {
787
+ "max_server_memory_usage" : cfg. query. max_server_memory_usage,
788
+ "max_memory_limit_enabled" : cfg. query. max_memory_limit_enabled,
789
+ "spill_enabled" : cfg. spill. global_bytes_limit > 0 ,
790
+ "reserved_disk_ratio" : cfg. spill. reserved_disk_ratio
791
+ } ,
792
+ "query_execution" : {
793
+ "max_running_queries" : cfg. query. max_running_queries,
794
+ "global_statement_queue" : cfg. query. global_statement_queue,
795
+ } ,
796
+ "storage_engine" : {
797
+ "table_engine_memory_enabled" : cfg. query. table_engine_memory_enabled,
798
+ "storage_type" : cfg. storage. params. to_string( ) ,
799
+ "storage_allow_insecure" : cfg. storage. allow_insecure
800
+ } ,
801
+ "meta_config" : {
802
+ "meta_embedded" : cfg. meta. embedded_dir. is_empty( ) ,
803
+ "meta_client_timeout" : cfg. meta. client_timeout_in_second,
804
+ "rpc_client_timeout_secs" : cfg. query. rpc_client_timeout_secs,
805
+ } ,
806
+ "license" : license_info,
807
+ "cluster_nodes" : {
808
+ "count" : online_nodes. as_ref( ) . map( |nodes| nodes. len( ) ) . unwrap_or( 0 ) ,
809
+ "nodes" : online_nodes. as_ref( ) . map( |nodes|
810
+ nodes. iter( ) . map( |node| serde_json:: json!( {
811
+ "id" : node. id,
812
+ "cpu_nums" : node. cpu_nums,
813
+ "version" : node. version,
814
+ "binary_version" : node. binary_version,
815
+ "cluster_id" : node. cluster_id,
816
+ "warehouse_id" : node. warehouse_id
817
+ } ) ) . collect:: <Vec <_>>( )
818
+ ) . unwrap_or_default( )
819
+ } ,
820
+ "observability" : {
821
+ "collection_duration_ms" : start_time. elapsed( ) . as_millis( ) as u64 ,
822
+ "report_timestamp" : std:: time:: SystemTime :: now( )
823
+ . duration_since( std:: time:: UNIX_EPOCH )
824
+ . map( |d| d. as_secs( ) )
825
+ . unwrap_or( 0 ) ,
826
+ "schema_version" : "1.0"
827
+ }
728
828
} ) ;
729
829
730
830
let _ = report_node_telemetry ( payload) . await ;
0 commit comments