diff --git a/.iwyu.imp b/.iwyu.imp index 02fc11c194..e2ab0e3b4e 100644 --- a/.iwyu.imp +++ b/.iwyu.imp @@ -14,6 +14,7 @@ # Work around for ryml { "include": ["", "private", "", "public"] }, + { "include": ["", "private", "", "public"] }, { "include": ["", "private", "", "public"] }, { "include": ["", "private", "", "public"] }, { "include": ["", "private", "", "public"] }, diff --git a/functional/configuration/shelltests/empty.test b/functional/configuration/shelltests/empty.test index ba6869976d..bad15c02d7 100644 --- a/functional/configuration/shelltests/empty.test +++ b/functional/configuration/shelltests/empty.test @@ -3,6 +3,6 @@ $ example_yaml --test --yaml shelltests/empty.yaml > -[ERROR] [Yaml Configuration Parser] Parse failed with exception: Yaml: not a map, looking for: file_format +[ERROR] :0[0](0): Yaml: not a map, looking for: file_format FAILED TO PARSE MODEL >= 1 diff --git a/functional/configuration/shelltests/format_empty.test b/functional/configuration/shelltests/format_empty.test index 820cea69a1..b540d1b8eb 100644 --- a/functional/configuration/shelltests/format_empty.test +++ b/functional/configuration/shelltests/format_empty.test @@ -3,6 +3,6 @@ $ example_yaml --test --yaml shelltests/format_empty.yaml > -[ERROR] [Yaml Configuration Parser] Parse failed with exception: Yaml: string value is empty: file_format +[ERROR] :4[0](94): Yaml: string value is empty: file_format FAILED TO PARSE MODEL >= 1 diff --git a/functional/configuration/shelltests/propagator_broken.test b/functional/configuration/shelltests/propagator_broken.test index b02b1f9c39..5265659346 100644 --- a/functional/configuration/shelltests/propagator_broken.test +++ b/functional/configuration/shelltests/propagator_broken.test @@ -3,6 +3,6 @@ $ example_yaml --test --yaml shelltests/propagator_broken.yaml > -[ERROR] [Yaml Configuration Parser] Parse failed with exception: Illegal composite child 2, properties count: 3 +[ERROR] :10[6](206): Illegal composite child 2, properties count: 3 FAILED TO PARSE MODEL >= 1 diff --git a/sdk/include/opentelemetry/sdk/configuration/configuration_parser.h b/sdk/include/opentelemetry/sdk/configuration/configuration_parser.h index fbf0db5edd..3ed39aef69 100644 --- a/sdk/include/opentelemetry/sdk/configuration/configuration_parser.h +++ b/sdk/include/opentelemetry/sdk/configuration/configuration_parser.h @@ -99,7 +99,8 @@ namespace configuration class ConfigurationParser { public: - OtlpHttpEncoding ParseOtlpHttpEncoding(const std::string &name) const; + OtlpHttpEncoding ParseOtlpHttpEncoding(const std::unique_ptr &node, + const std::string &name) const; std::unique_ptr ParseStringArrayConfiguration( const std::unique_ptr &node) const; @@ -151,9 +152,12 @@ class ConfigurationParser std::unique_ptr ParseLoggerProviderConfiguration( const std::unique_ptr &node) const; - DefaultHistogramAggregation ParseDefaultHistogramAggregation(const std::string &name) const; + DefaultHistogramAggregation ParseDefaultHistogramAggregation( + const std::unique_ptr &node, + const std::string &name) const; - TemporalityPreference ParseTemporalityPreference(const std::string &name) const; + TemporalityPreference ParseTemporalityPreference(const std::unique_ptr &node, + const std::string &name) const; std::unique_ptr ParseOtlpHttpPushMetricExporterConfiguration(const std::unique_ptr &node) const; @@ -203,7 +207,8 @@ class ConfigurationParser std::unique_ptr ParseMetricReaderConfiguration( const std::unique_ptr &node) const; - InstrumentType ParseInstrumentType(const std::string &name) const; + InstrumentType ParseInstrumentType(const std::unique_ptr &node, + const std::string &name) const; std::unique_ptr ParseViewSelectorConfiguration( const std::unique_ptr &node) const; diff --git a/sdk/include/opentelemetry/sdk/configuration/document_node.h b/sdk/include/opentelemetry/sdk/configuration/document_node.h index 1c3f4bef9f..646a15de17 100644 --- a/sdk/include/opentelemetry/sdk/configuration/document_node.h +++ b/sdk/include/opentelemetry/sdk/configuration/document_node.h @@ -16,6 +16,7 @@ namespace configuration class DocumentNodeConstIterator; class PropertiesNodeConstIterator; +class DocumentNodeLocation; class DocumentNode { @@ -30,6 +31,8 @@ class DocumentNode DocumentNode &operator=(const DocumentNode &other) = default; virtual ~DocumentNode() = default; + virtual DocumentNodeLocation Location() const = 0; + virtual std::string Key() const = 0; virtual bool AsBoolean() const = 0; @@ -172,6 +175,17 @@ class PropertiesNodeConstIterator std::unique_ptr impl_; }; +class DocumentNodeLocation +{ +public: + size_t offset; + size_t line; + size_t col; + std::string filename; + + std::string ToString() const; +}; + } // namespace configuration } // namespace sdk OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/include/opentelemetry/sdk/configuration/invalid_schema_exception.h b/sdk/include/opentelemetry/sdk/configuration/invalid_schema_exception.h index c6abe648b3..c4fe726af5 100644 --- a/sdk/include/opentelemetry/sdk/configuration/invalid_schema_exception.h +++ b/sdk/include/opentelemetry/sdk/configuration/invalid_schema_exception.h @@ -19,7 +19,14 @@ namespace configuration class InvalidSchemaException : public std::runtime_error { public: - InvalidSchemaException(const std::string &msg) : std::runtime_error(msg) {} + InvalidSchemaException(const DocumentNodeLocation &location, const std::string &msg) + : std::runtime_error(msg), location_(location) + {} + + std::string Where() const { return location_.ToString(); } + +private: + DocumentNodeLocation location_; }; } // namespace configuration diff --git a/sdk/include/opentelemetry/sdk/configuration/ryml_document.h b/sdk/include/opentelemetry/sdk/configuration/ryml_document.h index 8fa8ca13d0..9d464e63be 100644 --- a/sdk/include/opentelemetry/sdk/configuration/ryml_document.h +++ b/sdk/include/opentelemetry/sdk/configuration/ryml_document.h @@ -22,16 +22,23 @@ class RymlDocument : public Document public: static std::unique_ptr Parse(const std::string &source, const std::string &content); - RymlDocument(ryml::Tree tree) : tree_(std::move(tree)) {} + RymlDocument() {} RymlDocument(RymlDocument &&) = delete; RymlDocument(const RymlDocument &) = delete; RymlDocument &operator=(RymlDocument &&) = delete; RymlDocument &operator=(const RymlDocument &other) = delete; ~RymlDocument() override = default; + int ParseDocument(const std::string &source, const std::string &content); + std::unique_ptr GetRootNode() override; + DocumentNodeLocation Location(ryml::ConstNodeRef node) const; + private: + ryml::ParserOptions opts_; + ryml::Parser::handler_type event_handler_; + std::unique_ptr parser_; ryml::Tree tree_; }; diff --git a/sdk/include/opentelemetry/sdk/configuration/ryml_document_node.h b/sdk/include/opentelemetry/sdk/configuration/ryml_document_node.h index d524f57a21..82cdb8e683 100644 --- a/sdk/include/opentelemetry/sdk/configuration/ryml_document_node.h +++ b/sdk/include/opentelemetry/sdk/configuration/ryml_document_node.h @@ -17,16 +17,22 @@ namespace sdk namespace configuration { +class RymlDocument; + class RymlDocumentNode : public DocumentNode { public: - RymlDocumentNode(ryml::ConstNodeRef node, std::size_t depth) : node_(node), depth_(depth) {} + RymlDocumentNode(const RymlDocument *doc, ryml::ConstNodeRef node, std::size_t depth) + : doc_(doc), node_(node), depth_(depth) + {} RymlDocumentNode(RymlDocumentNode &&) = delete; RymlDocumentNode(const RymlDocumentNode &) = delete; RymlDocumentNode &operator=(RymlDocumentNode &&) = delete; RymlDocumentNode &operator=(const RymlDocumentNode &other) = delete; ~RymlDocumentNode() override = default; + DocumentNodeLocation Location() const override; + std::string Key() const override; bool AsBoolean() const override; @@ -62,6 +68,7 @@ class RymlDocumentNode : public DocumentNode ryml::ConstNodeRef GetRequiredRymlChildNode(const std::string &name) const; ryml::ConstNodeRef GetRymlChildNode(const std::string &name) const; + const RymlDocument *doc_; ryml::ConstNodeRef node_; std::size_t depth_; }; @@ -69,7 +76,8 @@ class RymlDocumentNode : public DocumentNode class RymlDocumentNodeConstIteratorImpl : public DocumentNodeConstIteratorImpl { public: - RymlDocumentNodeConstIteratorImpl(ryml::ConstNodeRef parent, + RymlDocumentNodeConstIteratorImpl(const RymlDocument *doc, + ryml::ConstNodeRef parent, std::size_t index, std::size_t depth); RymlDocumentNodeConstIteratorImpl(RymlDocumentNodeConstIteratorImpl &&) = delete; @@ -84,6 +92,7 @@ class RymlDocumentNodeConstIteratorImpl : public DocumentNodeConstIteratorImpl bool Equal(const DocumentNodeConstIteratorImpl *rhs) const override; private: + const RymlDocument *doc_; ryml::ConstNodeRef parent_; std::size_t index_; std::size_t depth_; @@ -92,7 +101,8 @@ class RymlDocumentNodeConstIteratorImpl : public DocumentNodeConstIteratorImpl class RymlPropertiesNodeConstIteratorImpl : public PropertiesNodeConstIteratorImpl { public: - RymlPropertiesNodeConstIteratorImpl(ryml::ConstNodeRef parent, + RymlPropertiesNodeConstIteratorImpl(const RymlDocument *doc, + ryml::ConstNodeRef parent, std::size_t index, std::size_t depth); RymlPropertiesNodeConstIteratorImpl(RymlPropertiesNodeConstIteratorImpl &&) = delete; @@ -108,6 +118,7 @@ class RymlPropertiesNodeConstIteratorImpl : public PropertiesNodeConstIteratorIm bool Equal(const PropertiesNodeConstIteratorImpl *rhs) const override; private: + const RymlDocument *doc_; ryml::ConstNodeRef parent_; std::size_t index_; std::size_t depth_; diff --git a/sdk/src/configuration/configuration_parser.cc b/sdk/src/configuration/configuration_parser.cc index 4cc2f53a6c..014ce84886 100644 --- a/sdk/src/configuration/configuration_parser.cc +++ b/sdk/src/configuration/configuration_parser.cc @@ -106,7 +106,9 @@ namespace configuration // FIXME: proper sizing constexpr size_t MAX_SAMPLER_DEPTH = 10; -OtlpHttpEncoding ConfigurationParser::ParseOtlpHttpEncoding(const std::string &name) const +OtlpHttpEncoding ConfigurationParser::ParseOtlpHttpEncoding( + const std::unique_ptr &node, + const std::string &name) const { if (name == "protobuf") { @@ -120,7 +122,7 @@ OtlpHttpEncoding ConfigurationParser::ParseOtlpHttpEncoding(const std::string &n std::string message("Illegal OtlpHttpEncoding: "); message.append(name); - throw InvalidSchemaException(message); + throw InvalidSchemaException(node->Location(), message); } std::unique_ptr ConfigurationParser::ParseStringArrayConfiguration( @@ -224,7 +226,7 @@ ConfigurationParser::ParseOtlpHttpLogRecordExporterConfiguration( model->timeout = node->GetInteger("timeout", 10000); std::string encoding = node->GetString("encoding", "protobuf"); - model->encoding = ParseOtlpHttpEncoding(encoding); + model->encoding = ParseOtlpHttpEncoding(node, encoding); return model; } @@ -310,7 +312,7 @@ ConfigurationParser::ParseLogRecordExporterConfiguration( { std::string message("Illegal log record exporter, count: "); message.append(std::to_string(count)); - throw InvalidSchemaException(message); + throw InvalidSchemaException(node->Location(), message); } if (name == "otlp_http") @@ -402,7 +404,7 @@ ConfigurationParser::ParseLogRecordProcessorConfiguration( { std::string message("Illegal log record processor, count: "); message.append(std::to_string(count)); - throw InvalidSchemaException(message); + throw InvalidSchemaException(node->Location(), message); } if (name == "batch") @@ -450,7 +452,7 @@ std::unique_ptr ConfigurationParser::ParseLoggerPro if (count == 0) { std::string message("Illegal logger provider, 0 processors"); - throw InvalidSchemaException(message); + throw InvalidSchemaException(child->Location(), message); } child = node->GetChildNode("limits"); @@ -463,6 +465,7 @@ std::unique_ptr ConfigurationParser::ParseLoggerPro } DefaultHistogramAggregation ConfigurationParser::ParseDefaultHistogramAggregation( + const std::unique_ptr &node, const std::string &name) const { if (name == "explicit_bucket_histogram") @@ -477,10 +480,12 @@ DefaultHistogramAggregation ConfigurationParser::ParseDefaultHistogramAggregatio std::string message("Illegal default_histogram_aggregation: "); message.append(name); - throw InvalidSchemaException(message); + throw InvalidSchemaException(node->Location(), message); } -TemporalityPreference ConfigurationParser::ParseTemporalityPreference(const std::string &name) const +TemporalityPreference ConfigurationParser::ParseTemporalityPreference( + const std::unique_ptr &node, + const std::string &name) const { if (name == "cumulative") { @@ -499,7 +504,7 @@ TemporalityPreference ConfigurationParser::ParseTemporalityPreference(const std: std::string message("Illegal temporality preference: "); message.append(name); - throw InvalidSchemaException(message); + throw InvalidSchemaException(node->Location(), message); } std::unique_ptr @@ -525,15 +530,15 @@ ConfigurationParser::ParseOtlpHttpPushMetricExporterConfiguration( model->timeout = node->GetInteger("timeout", 10000); std::string temporality_preference = node->GetString("temporality_preference", "cumulative"); - model->temporality_preference = ParseTemporalityPreference(temporality_preference); + model->temporality_preference = ParseTemporalityPreference(node, temporality_preference); std::string default_histogram_aggregation = node->GetString("default_histogram_aggregation", "explicit_bucket_histogram"); model->default_histogram_aggregation = - ParseDefaultHistogramAggregation(default_histogram_aggregation); + ParseDefaultHistogramAggregation(node, default_histogram_aggregation); std::string encoding = node->GetString("encoding", "protobuf"); - model->encoding = ParseOtlpHttpEncoding(encoding); + model->encoding = ParseOtlpHttpEncoding(node, encoding); return model; } @@ -561,12 +566,12 @@ ConfigurationParser::ParseOtlpGrpcPushMetricExporterConfiguration( model->timeout = node->GetInteger("timeout", 10000); std::string temporality_preference = node->GetString("temporality_preference", "cumulative"); - model->temporality_preference = ParseTemporalityPreference(temporality_preference); + model->temporality_preference = ParseTemporalityPreference(node, temporality_preference); std::string default_histogram_aggregation = node->GetString("default_histogram_aggregation", "explicit_bucket_histogram"); model->default_histogram_aggregation = - ParseDefaultHistogramAggregation(default_histogram_aggregation); + ParseDefaultHistogramAggregation(node, default_histogram_aggregation); model->insecure = node->GetBoolean("insecure", false); @@ -583,12 +588,12 @@ ConfigurationParser::ParseOtlpFilePushMetricExporterConfiguration( model->output_stream = node->GetString("output_stream", ""); std::string temporality_preference = node->GetString("temporality_preference", "cumulative"); - model->temporality_preference = ParseTemporalityPreference(temporality_preference); + model->temporality_preference = ParseTemporalityPreference(node, temporality_preference); std::string default_histogram_aggregation = node->GetString("default_histogram_aggregation", "explicit_bucket_histogram"); model->default_histogram_aggregation = - ParseDefaultHistogramAggregation(default_histogram_aggregation); + ParseDefaultHistogramAggregation(node, default_histogram_aggregation); return model; } @@ -666,7 +671,7 @@ ConfigurationParser::ParsePushMetricExporterConfiguration( { std::string message("Illegal push metric exporter, count: "); message.append(std::to_string(count)); - throw InvalidSchemaException(message); + throw InvalidSchemaException(node->Location(), message); } if (name == "otlp_http") @@ -714,7 +719,7 @@ ConfigurationParser::ParsePullMetricExporterConfiguration( { std::string message("Illegal pull metric exporter, count: "); message.append(std::to_string(count)); - throw InvalidSchemaException(message); + throw InvalidSchemaException(node->Location(), message); } if (name == "prometheus/development") @@ -771,7 +776,7 @@ std::unique_ptr ConfigurationParser::ParseMetricPro { std::string message("Illegal metric producer, properties count: "); message.append(std::to_string(count)); - throw InvalidSchemaException(message); + throw InvalidSchemaException(node->Location(), message); } if (name == "opencensus") @@ -855,7 +860,7 @@ std::unique_ptr ConfigurationParser::ParseMetricReade { std::string message("Illegal metric reader, count: "); message.append(std::to_string(count)); - throw InvalidSchemaException(message); + throw InvalidSchemaException(node->Location(), message); } if (name == "periodic") @@ -870,13 +875,14 @@ std::unique_ptr ConfigurationParser::ParseMetricReade { std::string message("Illegal metric reader: "); message.append(name); - throw InvalidSchemaException(message); + throw InvalidSchemaException(node->Location(), message); } return model; } -InstrumentType ConfigurationParser::ParseInstrumentType(const std::string &name) const +InstrumentType ConfigurationParser::ParseInstrumentType(const std::unique_ptr &node, + const std::string &name) const { if (name == "") { @@ -915,7 +921,7 @@ InstrumentType ConfigurationParser::ParseInstrumentType(const std::string &name) std::string message("Illegal instrument type: "); message.append(name); - throw InvalidSchemaException(message); + throw InvalidSchemaException(node->Location(), message); } std::unique_ptr ConfigurationParser::ParseViewSelectorConfiguration( @@ -926,7 +932,7 @@ std::unique_ptr ConfigurationParser::ParseViewSelecto model->instrument_name = node->GetString("instrument_name", ""); std::string instrument_type = node->GetString("instrument_type", ""); - model->instrument_type = ParseInstrumentType(instrument_type); + model->instrument_type = ParseInstrumentType(node, instrument_type); model->unit = node->GetString("unit", ""); model->meter_name = node->GetString("meter_name", ""); @@ -1022,7 +1028,7 @@ std::unique_ptr ConfigurationParser::ParseAggregationC { std::string message("Illegal aggregation, children: "); message.append(std::to_string(count)); - throw InvalidSchemaException(message); + throw InvalidSchemaException(node->Location(), message); } child = node->GetChild(0); @@ -1056,7 +1062,7 @@ std::unique_ptr ConfigurationParser::ParseAggregationC { std::string message("Illegal aggregation: "); message.append(name); - throw InvalidSchemaException(message); + throw InvalidSchemaException(node->Location(), message); } return model; @@ -1118,7 +1124,7 @@ std::unique_ptr ConfigurationParser::ParseMeterProvi if (model->readers.size() == 0) { std::string message("Illegal meter provider, 0 readers"); - throw InvalidSchemaException(message); + throw InvalidSchemaException(child->Location(), message); } child = node->GetChildNode("views"); @@ -1166,7 +1172,7 @@ std::unique_ptr ConfigurationParser::ParsePropagatorCon message.append(std::to_string(num_child)); message.append(", properties count: "); message.append(std::to_string(count)); - throw InvalidSchemaException(message); + throw InvalidSchemaException(element->Location(), message); } model->composite.push_back(name); @@ -1321,7 +1327,7 @@ std::unique_ptr ConfigurationParser::ParseSamplerConfigura { std::string message("Samplers nested too deeply: "); message.append(std::to_string(depth)); - throw InvalidSchemaException(message); + throw InvalidSchemaException(node->Location(), message); } std::unique_ptr model; @@ -1341,7 +1347,7 @@ std::unique_ptr ConfigurationParser::ParseSamplerConfigura { std::string message("Illegal sampler, properties count: "); message.append(std::to_string(count)); - throw InvalidSchemaException(message); + throw InvalidSchemaException(node->Location(), message); } if (name == "always_off") @@ -1396,7 +1402,7 @@ ConfigurationParser::ParseOtlpHttpSpanExporterConfiguration( model->timeout = node->GetInteger("timeout", 10000); std::string encoding = node->GetString("encoding", "protobuf"); - model->encoding = ParseOtlpHttpEncoding(encoding); + model->encoding = ParseOtlpHttpEncoding(node, encoding); return model; } @@ -1493,7 +1499,7 @@ std::unique_ptr ConfigurationParser::ParseSpanExporte { std::string message("Illegal span exporter, properties count: "); message.append(std::to_string(count)); - throw InvalidSchemaException(message); + throw InvalidSchemaException(node->Location(), message); } if (name == "otlp_http") @@ -1588,7 +1594,7 @@ std::unique_ptr ConfigurationParser::ParseSpanProces { std::string message("Illegal span processor, properties count: "); message.append(std::to_string(count)); - throw InvalidSchemaException(message); + throw InvalidSchemaException(node->Location(), message); } if (name == "batch") @@ -1624,7 +1630,7 @@ std::unique_ptr ConfigurationParser::ParseTracerPro if (count == 0) { std::string message("Illegal tracer provider, 0 processors"); - throw InvalidSchemaException(message); + throw InvalidSchemaException(node->Location(), message); } child = node->GetChildNode("limits"); @@ -1835,7 +1841,7 @@ std::unique_ptr ConfigurationParser::ParseAttributesCon { std::string message("Illegal attribute type: "); message.append(type); - throw InvalidSchemaException(message); + throw InvalidSchemaException(node->Location(), message); } std::pair> entry( @@ -1887,14 +1893,14 @@ std::unique_ptr ConfigurationParser::Parse(std::unique_ptrLocation(), message); } if (major != 1) { std::string message("Unsupported file_format, major = "); message.append(std::to_string(major)); - throw InvalidSchemaException(message); + throw InvalidSchemaException(node->Location(), message); } if (minor != 0) @@ -1903,7 +1909,7 @@ std::unique_ptr ConfigurationParser::Parse(std::unique_ptr:line-number[column-number](offset) + std::string where; + where.append("<"); + where.append(filename); + where.append(">:"); + where.append(std::to_string(line)); + where.append("["); + where.append(std::to_string(col)); + where.append("]("); + where.append(std::to_string(offset)); + where.append(")"); + return where; +} + } // namespace configuration } // namespace sdk OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/src/configuration/ryml_document.cc b/sdk/src/configuration/ryml_document.cc index 24968bcc0e..facb8282cb 100644 --- a/sdk/src/configuration/ryml_document.cc +++ b/sdk/src/configuration/ryml_document.cc @@ -23,46 +23,66 @@ namespace configuration std::unique_ptr RymlDocument::Parse(const std::string &source, const std::string &content) { - ryml::ParserOptions opts; - opts.locations(true); + auto doc = std::make_unique(); + int rc; - ryml::Parser::handler_type event_handler; - ryml::Parser parser(&event_handler, opts); + rc = doc->ParseDocument(source, content); + if (rc == 0) + { + return doc; + } + + return nullptr; +} + +int RymlDocument::ParseDocument(const std::string &source, const std::string &content) +{ + opts_.locations(true); + parser_ = std::make_unique(&event_handler_, opts_); - ryml::Tree tree; ryml::csubstr filename; ryml::csubstr csubstr_content; - std::unique_ptr doc; filename = ryml::to_csubstr(source); csubstr_content = ryml::to_csubstr(content); try { - tree = parse_in_arena(&parser, filename, csubstr_content); - tree.resolve(); + tree_ = parse_in_arena(parser_.get(), filename, csubstr_content); + tree_.resolve(); } catch (const std::exception &e) { OTEL_INTERNAL_LOG_ERROR("[Ryml Document] Parse failed with exception: " << e.what()); - return doc; + return 1; } catch (...) { OTEL_INTERNAL_LOG_ERROR("[Ryml Document] Parse failed with unknown exception."); - return doc; + return 2; } - doc = std::make_unique(tree); - return doc; + return 0; } std::unique_ptr RymlDocument::GetRootNode() { - auto node = std::make_unique(tree_.rootref(), 0); + auto node = std::make_unique(this, tree_.rootref(), 0); return node; } +DocumentNodeLocation RymlDocument::Location(ryml::ConstNodeRef node) const +{ + DocumentNodeLocation loc; + auto ryml_loc = parser_->location(node); + loc.offset = ryml_loc.offset; + loc.line = ryml_loc.line; + loc.col = ryml_loc.col; + loc.filename = std::string(ryml_loc.name.str, ryml_loc.name.len); + + return loc; +} + } // namespace configuration } // namespace sdk OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/src/configuration/ryml_document_node.cc b/sdk/src/configuration/ryml_document_node.cc index 286c4f8e5b..53d3a06d37 100644 --- a/sdk/src/configuration/ryml_document_node.cc +++ b/sdk/src/configuration/ryml_document_node.cc @@ -5,12 +5,14 @@ #include #include #include +#include #include #include #include "opentelemetry/sdk/common/global_log_handler.h" #include "opentelemetry/sdk/configuration/document_node.h" #include "opentelemetry/sdk/configuration/invalid_schema_exception.h" +#include "opentelemetry/sdk/configuration/ryml_document.h" #include "opentelemetry/sdk/configuration/ryml_document_node.h" #include "opentelemetry/version.h" @@ -48,13 +50,18 @@ static void DebugNode(opentelemetry::nostd::string_view name, ryml::ConstNodeRef } #endif // WITH_DEBUG_NODE +DocumentNodeLocation RymlDocumentNode::Location() const +{ + return doc_->Location(node_); +} + std::string RymlDocumentNode::Key() const { OTEL_INTERNAL_LOG_DEBUG("RymlDocumentNode::Key()"); if (!node_.has_key()) { - throw InvalidSchemaException("Yaml: no key"); + throw InvalidSchemaException(Location(), "Yaml: no key"); } ryml::csubstr k = node_.key(); @@ -68,7 +75,7 @@ bool RymlDocumentNode::AsBoolean() const if (!node_.is_val() && !node_.is_keyval()) { - throw InvalidSchemaException("Yaml: not scalar"); + throw InvalidSchemaException(Location(), "Yaml: not scalar"); } ryml::csubstr view = node_.val(); std::string value(view.str, view.len); @@ -81,7 +88,7 @@ size_t RymlDocumentNode::AsInteger() const if (!node_.is_val() && !node_.is_keyval()) { - throw InvalidSchemaException("Yaml: not scalar"); + throw InvalidSchemaException(Location(), "Yaml: not scalar"); } ryml::csubstr view = node_.val(); std::string value(view.str, view.len); @@ -94,7 +101,7 @@ double RymlDocumentNode::AsDouble() const if (!node_.is_val() && !node_.is_keyval()) { - throw InvalidSchemaException("Yaml: not scalar"); + throw InvalidSchemaException(Location(), "Yaml: not scalar"); } ryml::csubstr view = node_.val(); std::string value(view.str, view.len); @@ -107,7 +114,7 @@ std::string RymlDocumentNode::AsString() const if (!node_.is_val() && !node_.is_keyval()) { - throw InvalidSchemaException("Yaml: not scalar"); + throw InvalidSchemaException(Location(), "Yaml: not scalar"); } ryml::csubstr view = node_.val(); std::string value(view.str, view.len); @@ -120,7 +127,7 @@ ryml::ConstNodeRef RymlDocumentNode::GetRequiredRymlChildNode(const std::string { std::string message("Yaml: not a map, looking for: "); message.append(name); - throw InvalidSchemaException(message); + throw InvalidSchemaException(Location(), message); } const char *name_str = name.c_str(); @@ -128,7 +135,7 @@ ryml::ConstNodeRef RymlDocumentNode::GetRequiredRymlChildNode(const std::string { std::string message("Yaml: required node: "); message.append(name); - throw InvalidSchemaException(message); + throw InvalidSchemaException(Location(), message); } ryml::ConstNodeRef ryml_child = node_[name_str]; @@ -161,11 +168,11 @@ std::unique_ptr RymlDocumentNode::GetRequiredChildNode(const std:: { std::string message("Yaml nested too deeply: "); message.append(name); - throw InvalidSchemaException(message); + throw InvalidSchemaException(Location(), message); } auto ryml_child = GetRequiredRymlChildNode(name); - auto child = std::make_unique(ryml_child, depth_ + 1); + auto child = std::make_unique(doc_, ryml_child, depth_ + 1); return child; } @@ -177,7 +184,7 @@ std::unique_ptr RymlDocumentNode::GetChildNode(const std::string & { std::string message("Yaml nested too deeply: "); message.append(name); - throw InvalidSchemaException(message); + throw InvalidSchemaException(Location(), message); } std::unique_ptr child; @@ -194,7 +201,7 @@ std::unique_ptr RymlDocumentNode::GetChildNode(const std::string & } ryml::ConstNodeRef ryml_child = node_[name_str]; - child = std::make_unique(ryml_child, depth_ + 1); + child = std::make_unique(doc_, ryml_child, depth_ + 1); return child; } @@ -326,7 +333,7 @@ std::string RymlDocumentNode::GetRequiredString(const std::string &name) const { std::string message("Yaml: string value is empty: "); message.append(name); - throw InvalidSchemaException(message); + throw InvalidSchemaException(Location(), message); } return value; @@ -365,7 +372,7 @@ DocumentNodeConstIterator RymlDocumentNode::begin() const } #endif // WITH_DEBUG_NODE - auto impl = std::make_unique(node_, 0, depth_); + auto impl = std::make_unique(doc_, node_, 0, depth_); return DocumentNodeConstIterator(std::move(impl)); } @@ -374,8 +381,8 @@ DocumentNodeConstIterator RymlDocumentNode::end() const { OTEL_INTERNAL_LOG_DEBUG("RymlDocumentNode::end()"); - auto impl = - std::make_unique(node_, node_.num_children(), depth_); + auto impl = std::make_unique(doc_, node_, node_.num_children(), + depth_); return DocumentNodeConstIterator(std::move(impl)); } @@ -389,7 +396,7 @@ std::unique_ptr RymlDocumentNode::GetChild(size_t index) const { std::unique_ptr child; ryml::ConstNodeRef ryml_child = node_[index]; - child = std::make_unique(ryml_child, depth_ + 1); + child = std::make_unique(doc_, ryml_child, depth_ + 1); return child; } @@ -406,7 +413,7 @@ PropertiesNodeConstIterator RymlDocumentNode::begin_properties() const } #endif // WITH_DEBUG_NODE - auto impl = std::make_unique(node_, 0, depth_); + auto impl = std::make_unique(doc_, node_, 0, depth_); return PropertiesNodeConstIterator(std::move(impl)); } @@ -415,16 +422,17 @@ PropertiesNodeConstIterator RymlDocumentNode::end_properties() const { OTEL_INTERNAL_LOG_DEBUG("RymlDocumentNode::end_properties()"); - auto impl = - std::make_unique(node_, node_.num_children(), depth_); + auto impl = std::make_unique(doc_, node_, + node_.num_children(), depth_); return PropertiesNodeConstIterator(std::move(impl)); } -RymlDocumentNodeConstIteratorImpl::RymlDocumentNodeConstIteratorImpl(ryml::ConstNodeRef parent, +RymlDocumentNodeConstIteratorImpl::RymlDocumentNodeConstIteratorImpl(const RymlDocument *doc, + ryml::ConstNodeRef parent, size_t index, size_t depth) - : parent_(parent), index_(index), depth_(depth) + : doc_(doc), parent_(parent), index_(index), depth_(depth) {} RymlDocumentNodeConstIteratorImpl::~RymlDocumentNodeConstIteratorImpl() {} @@ -440,10 +448,9 @@ std::unique_ptr RymlDocumentNodeConstIteratorImpl::Item() const ryml::ConstNodeRef ryml_item = parent_[index_]; if (ryml_item.invalid()) { - // FIXME: runtime exception really - throw InvalidSchemaException("iterator is lost"); + throw std::runtime_error("iterator is lost"); } - item = std::make_unique(ryml_item, depth_ + 1); + item = std::make_unique(doc_, ryml_item, depth_ + 1); return item; } @@ -454,10 +461,11 @@ bool RymlDocumentNodeConstIteratorImpl::Equal(const DocumentNodeConstIteratorImp return index_ == other->index_; } -RymlPropertiesNodeConstIteratorImpl::RymlPropertiesNodeConstIteratorImpl(ryml::ConstNodeRef parent, +RymlPropertiesNodeConstIteratorImpl::RymlPropertiesNodeConstIteratorImpl(const RymlDocument *doc, + ryml::ConstNodeRef parent, size_t index, size_t depth) - : parent_(parent), index_(index), depth_(depth) + : doc_(doc), parent_(parent), index_(index), depth_(depth) {} RymlPropertiesNodeConstIteratorImpl::~RymlPropertiesNodeConstIteratorImpl() {} @@ -485,7 +493,7 @@ std::unique_ptr RymlPropertiesNodeConstIteratorImpl::Value() const std::unique_ptr item; ryml::ConstNodeRef ryml_item = parent_[index_]; - item = std::make_unique(ryml_item, depth_ + 1); + item = std::make_unique(doc_, ryml_item, depth_ + 1); OTEL_INTERNAL_LOG_DEBUG("RymlPropertiesNodeConstIteratorImpl::Value()"); diff --git a/sdk/src/configuration/yaml_configuration_parser.cc b/sdk/src/configuration/yaml_configuration_parser.cc index 665efa927a..7c95b1c895 100644 --- a/sdk/src/configuration/yaml_configuration_parser.cc +++ b/sdk/src/configuration/yaml_configuration_parser.cc @@ -13,6 +13,7 @@ #include "opentelemetry/sdk/configuration/configuration.h" #include "opentelemetry/sdk/configuration/configuration_parser.h" #include "opentelemetry/sdk/configuration/document.h" +#include "opentelemetry/sdk/configuration/invalid_schema_exception.h" #include "opentelemetry/sdk/configuration/ryml_document.h" #include "opentelemetry/sdk/configuration/yaml_configuration_parser.h" #include "opentelemetry/version.h" @@ -77,6 +78,10 @@ std::unique_ptr YamlConfigurationParser::ParseString(const std::s config = config_parser.Parse(std::move(doc)); } } + catch (const InvalidSchemaException &e) + { + OTEL_INTERNAL_LOG_ERROR(e.Where() << ": " << e.what()); + } catch (const std::exception &e) { OTEL_INTERNAL_LOG_ERROR(