@@ -443,6 +443,85 @@ INSTANTIATE_TEST_SUITE_P(
443443 .ConsumeValueOrDie ();
444444 },
445445 },
446+ {
447+ " logs_basic" ,
448+ table_store::schema::Relation{
449+ {types::TIME64NS, types::STRING, types::STRING},
450+ {" start_time" , " attribute_str" , " log_message" },
451+ {types::ST_NONE, types::ST_NONE, types::ST_NONE}},
452+ R"pb(
453+ endpoint_config {}
454+ resource {}
455+ logs {
456+ attributes {
457+ name: "service.name"
458+ column {
459+ column_type: STRING
460+ column_index: 1
461+ }
462+ }
463+ time_column_index: 0
464+ observed_time_column_index: -1
465+ severity_number: 4
466+ severity_text: "INFO"
467+ body_column_index: 2
468+ }
469+ )pb" ,
470+ [](IR* graph, OperatorIR* parent, table_store::schema::Relation* relation) {
471+ OTelData data;
472+
473+ auto & log = data.logs .emplace_back ();
474+ log.time_column = CreateTypedColumn (graph, " start_time" , relation);
475+ log.attributes .push_back (
476+ {" service.name" , CreateTypedColumn (graph, " attribute_str" , relation), " " });
477+ log.severity_number = 4 ;
478+ log.severity_text = " INFO" ;
479+ log.body_column = CreateTypedColumn (graph, " log_message" , relation);
480+
481+ return graph->CreateNode <OTelExportSinkIR>(parent->ast (), parent, data)
482+ .ConsumeValueOrDie ();
483+ },
484+ },
485+ {
486+ " logs_with_observed_time_col" ,
487+ table_store::schema::Relation{
488+ {types::TIME64NS, types::TIME64NS, types::STRING, types::STRING},
489+ {" start_time" , " observed_time" , " attribute_str" , " log_message" },
490+ {types::ST_NONE, types::ST_NONE, types::ST_NONE, types::ST_NONE}},
491+ R"pb(
492+ endpoint_config {}
493+ resource {}
494+ logs {
495+ attributes {
496+ name: "service.name"
497+ column {
498+ column_type: STRING
499+ column_index: 2
500+ }
501+ }
502+ time_column_index: 0
503+ observed_time_column_index: 1
504+ severity_number: 4
505+ severity_text: "INFO"
506+ body_column_index: 3
507+ }
508+ )pb" ,
509+ [](IR* graph, OperatorIR* parent, table_store::schema::Relation* relation) {
510+ OTelData data;
511+
512+ auto & log = data.logs .emplace_back ();
513+ log.time_column = CreateTypedColumn (graph, " start_time" , relation);
514+ log.observed_time_column = CreateTypedColumn (graph, " observed_time" , relation);
515+ log.attributes .push_back (
516+ {" service.name" , CreateTypedColumn (graph, " attribute_str" , relation), " " });
517+ log.severity_number = 4 ;
518+ log.severity_text = " INFO" ;
519+ log.body_column = CreateTypedColumn (graph, " log_message" , relation);
520+
521+ return graph->CreateNode <OTelExportSinkIR>(parent->ast (), parent, data)
522+ .ConsumeValueOrDie ();
523+ },
524+ },
446525 {
447526 " string_value_attributes" ,
448527 table_store::schema::Relation{{types::TIME64NS, types::INT64},
@@ -557,6 +636,33 @@ OTelExportSinkIR* CreateSpanWithNameString(IR* graph, OperatorIR* parent,
557636 return graph->CreateNode <OTelExportSinkIR>(parent->ast (), parent, data).ConsumeValueOrDie ();
558637}
559638
639+ OTelExportSinkIR* CreateLog (IR* graph, OperatorIR* parent,
640+ table_store::schema::Relation* relation) {
641+ OTelData data;
642+
643+ auto & log = data.logs .emplace_back ();
644+ log.time_column = CreateTypedColumn (graph, " start_time" , relation);
645+ log.body_column = CreateTypedColumn (graph, " log_message" , relation);
646+ log.severity_number = 4 ;
647+ log.severity_text = " INFO" ;
648+
649+ return graph->CreateNode <OTelExportSinkIR>(parent->ast (), parent, data).ConsumeValueOrDie ();
650+ }
651+
652+ OTelExportSinkIR* CreateLogWithObservedTime (IR* graph, OperatorIR* parent,
653+ table_store::schema::Relation* relation) {
654+ OTelData data;
655+
656+ auto & log = data.logs .emplace_back ();
657+ log.time_column = CreateTypedColumn (graph, " start_time" , relation);
658+ log.observed_time_column = CreateTypedColumn (graph, " observed_time" , relation);
659+ log.body_column = CreateTypedColumn (graph, " log_message" , relation);
660+ log.severity_number = 4 ;
661+ log.severity_text = " INFO" ;
662+
663+ return graph->CreateNode <OTelExportSinkIR>(parent->ast (), parent, data).ConsumeValueOrDie ();
664+ }
665+
560666INSTANTIATE_TEST_SUITE_P (
561667 ErrorTests, WrongColumnTypesTest,
562668 ::testing::ValuesIn (std::vector<WrongColumnTypesTestCase>{
@@ -723,6 +829,33 @@ INSTANTIATE_TEST_SUITE_P(
723829 .ConsumeValueOrDie ();
724830 },
725831 },
832+ {
833+ " log_time_column_wrong" ,
834+ table_store::schema::Relation{
835+ {types::INT64, types::STRING, types::STRING},
836+ {" start_time" , " attribute_str" , " log_message" },
837+ {types::ST_NONE, types::ST_NONE, types::ST_NONE}},
838+ " Expected time column 'start_time' to be TIME64NS, received INT64" ,
839+ &CreateLog,
840+ },
841+ {
842+ " log_body_column_wrong" ,
843+ table_store::schema::Relation{
844+ {types::TIME64NS, types::STRING, types::TIME64NS},
845+ {" start_time" , " attribute_str" , " log_message" },
846+ {types::ST_NONE, types::ST_NONE, types::ST_NONE}},
847+ " Expected body column 'log_message' to be STRING, received TIME64NS" ,
848+ &CreateLog,
849+ },
850+ {
851+ " log_observed_time_column_wrong" ,
852+ table_store::schema::Relation{
853+ {types::TIME64NS, types::INT64, types::STRING, types::STRING},
854+ {" start_time" , " observed_time" , " attribute_str" , " log_message" },
855+ {types::ST_NONE, types::ST_NONE, types::ST_NONE, types::ST_NONE}},
856+ " Expected observed_time column 'observed_time' to be TIME64NS, received INT64" ,
857+ &CreateLogWithObservedTime,
858+ },
726859 }),
727860 [](const ::testing::TestParamInfo<WrongColumnTypesTestCase>& info) { return info.param .name ; });
728861} // namespace planner
0 commit comments