Skip to content

Commit 87a11de

Browse files
evindjInnocent
andauthored
feat: metrics integration for commit and scan (#701)
This change implements part 2 of the core metrics. it covers RestCatalog spec, integration with commit and scan workflows. It leaves the logging metrics reporter out of scope, it will be added in a subsequent diff. some other differences is that some of the http calls for the RestCatalogMetrics reporter is still synchronous a subsequent change will cover that. --------- Co-authored-by: Innocent <idjiofack@jabode.com>
1 parent 41435b8 commit 87a11de

58 files changed

Lines changed: 3098 additions & 188 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

example/demo_example.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919

2020
#include <iostream>
21+
#include <utility>
2122

2223
#include "iceberg/arrow/arrow_io_util.h"
2324
#include "iceberg/avro/avro_register.h"
@@ -42,8 +43,14 @@ int main(int argc, char** argv) {
4243
iceberg::avro::RegisterAll();
4344
iceberg::parquet::RegisterAll();
4445

45-
auto catalog = iceberg::InMemoryCatalog::Make("test", iceberg::arrow::MakeLocalFileIO(),
46-
warehouse_location, properties);
46+
auto catalog_result = iceberg::InMemoryCatalog::Make(
47+
"test", iceberg::arrow::MakeLocalFileIO(), warehouse_location, properties);
48+
if (!catalog_result.has_value()) {
49+
std::cerr << "Failed to create catalog: " << catalog_result.error().message
50+
<< std::endl;
51+
return 1;
52+
}
53+
auto catalog = std::move(catalog_result.value());
4754

4855
auto register_result = catalog->RegisterTable({.name = table_name}, table_location);
4956
if (!register_result.has_value()) {

src/iceberg/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ set(ICEBERG_SOURCES
2121
arrow_c_data_guard_internal.cc
2222
arrow_c_data_util.cc
2323
arrow_row_builder.cc
24+
catalog/catalog_util.cc
2425
catalog/memory/in_memory_catalog.cc
2526
catalog/session_catalog.cc
2627
catalog/session_context.cc
@@ -39,6 +40,7 @@ set(ICEBERG_SOURCES
3940
expression/projections.cc
4041
expression/residual_evaluator.cc
4142
expression/rewrite_not.cc
43+
expression/sanitize_expression.cc
4244
expression/strict_metrics_evaluator.cc
4345
expression/term.cc
4446
file_io.cc
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#include "iceberg/catalog/catalog_util.h"
21+
22+
#include "iceberg/table_identifier.h"
23+
24+
namespace iceberg {
25+
26+
std::string CatalogUtil::FullTableName(std::string_view catalog_name,
27+
const TableIdentifier& identifier) {
28+
if (catalog_name.empty()) {
29+
return identifier.ToString();
30+
}
31+
32+
std::string result;
33+
if (catalog_name.contains('/') || catalog_name.contains(':')) {
34+
result = catalog_name;
35+
if (!catalog_name.ends_with('/')) {
36+
result += '/';
37+
}
38+
} else {
39+
result = std::string(catalog_name) + '.';
40+
}
41+
42+
for (const auto& level : identifier.ns.levels) {
43+
result += level + '.';
44+
}
45+
result += identifier.name;
46+
return result;
47+
}
48+
49+
} // namespace iceberg

src/iceberg/catalog/catalog_util.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
#pragma once
21+
22+
#include <string>
23+
#include <string_view>
24+
25+
#include "iceberg/iceberg_export.h"
26+
#include "iceberg/type_fwd.h"
27+
28+
namespace iceberg {
29+
30+
/// \brief Utilities for working with catalogs.
31+
class ICEBERG_EXPORT CatalogUtil {
32+
public:
33+
/// \brief Return the fully-qualified name for a table in a catalog.
34+
static std::string FullTableName(std::string_view catalog_name,
35+
const TableIdentifier& identifier);
36+
};
37+
38+
} // namespace iceberg

src/iceberg/catalog/memory/in_memory_catalog.cc

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
#include <algorithm>
2323
#include <iterator>
2424

25+
#include "iceberg/catalog/catalog_util.h"
2526
#include "iceberg/file_io.h"
27+
#include "iceberg/metrics/metrics_reporters.h"
2628
#include "iceberg/table.h"
2729
#include "iceberg/table_identifier.h"
2830
#include "iceberg/table_metadata.h"
@@ -337,22 +339,30 @@ Status InMemoryNamespace::UpdateTableMetadataLocation(
337339
return {};
338340
}
339341

340-
std::shared_ptr<InMemoryCatalog> InMemoryCatalog::Make(
342+
Result<std::shared_ptr<InMemoryCatalog>> InMemoryCatalog::Make(
341343
const std::string& name, const std::shared_ptr<FileIO>& file_io,
342344
const std::string& warehouse_location,
343345
const std::unordered_map<std::string, std::string>& properties) {
344-
return std::make_shared<InMemoryCatalog>(name, file_io, warehouse_location, properties);
346+
std::shared_ptr<MetricsReporter> reporter;
347+
auto it = properties.find(std::string(kMetricsReporterImpl));
348+
if (it != properties.end() && !it->second.empty() &&
349+
it->second != kMetricsReporterTypeNoop) {
350+
ICEBERG_ASSIGN_OR_RAISE(reporter, MetricsReporters::Load(properties));
351+
}
352+
return std::make_shared<InMemoryCatalog>(name, file_io, warehouse_location, properties,
353+
std::move(reporter));
345354
}
346355

347-
InMemoryCatalog::InMemoryCatalog(
348-
const std::string& name, const std::shared_ptr<FileIO>& file_io,
349-
const std::string& warehouse_location,
350-
const std::unordered_map<std::string, std::string>& properties)
356+
InMemoryCatalog::InMemoryCatalog(std::string name, std::shared_ptr<FileIO> file_io,
357+
std::string warehouse_location,
358+
std::unordered_map<std::string, std::string> properties,
359+
std::shared_ptr<MetricsReporter> reporter)
351360
: catalog_name_(std::move(name)),
352361
properties_(std::move(properties)),
353362
file_io_(std::move(file_io)),
354363
warehouse_location_(std::move(warehouse_location)),
355-
root_namespace_(std::make_unique<InMemoryNamespace>()) {}
364+
root_namespace_(std::make_unique<InMemoryNamespace>()),
365+
reporter_(std::move(reporter)) {}
356366

357367
InMemoryCatalog::~InMemoryCatalog() = default;
358368

@@ -429,7 +439,8 @@ Result<std::shared_ptr<Table>> InMemoryCatalog::CreateTable(
429439
ICEBERG_RETURN_UNEXPECTED(
430440
root_namespace_->UpdateTableMetadataLocation(identifier, metadata_file_location));
431441
return Table::Make(identifier, std::move(table_metadata),
432-
std::move(metadata_file_location), file_io_, shared_from_this());
442+
std::move(metadata_file_location), file_io_, shared_from_this(),
443+
CatalogUtil::FullTableName(name(), identifier), reporter_);
433444
}
434445

435446
Result<std::shared_ptr<Table>> InMemoryCatalog::UpdateTable(
@@ -480,7 +491,8 @@ Result<std::shared_ptr<Table>> InMemoryCatalog::UpdateTable(
480491
TableMetadataUtil::DeleteRemovedMetadataFiles(*file_io_, base.get(), *updated);
481492

482493
return Table::Make(identifier, std::move(updated), std::move(new_metadata_location),
483-
file_io_, shared_from_this());
494+
file_io_, shared_from_this(),
495+
CatalogUtil::FullTableName(name(), identifier), reporter_);
484496
}
485497

486498
Result<std::shared_ptr<Transaction>> InMemoryCatalog::StageCreateTable(
@@ -500,8 +512,10 @@ Result<std::shared_ptr<Transaction>> InMemoryCatalog::StageCreateTable(
500512
auto table_metadata,
501513
TableMetadata::Make(*schema, *spec, *order, base_location, properties));
502514
ICEBERG_ASSIGN_OR_RAISE(
503-
auto table, StagedTable::Make(identifier, std::move(table_metadata), "", file_io_,
504-
shared_from_this()));
515+
auto table,
516+
StagedTable::Make(identifier, std::move(table_metadata), "", file_io_,
517+
shared_from_this(),
518+
CatalogUtil::FullTableName(name(), identifier), reporter_));
505519
return Transaction::Make(std::move(table), TransactionKind::kCreate);
506520
}
507521

@@ -581,7 +595,8 @@ Result<std::shared_ptr<Table>> InMemoryCatalog::LoadTable(
581595
ICEBERG_ASSIGN_OR_RAISE(auto metadata,
582596
TableMetadataUtil::Read(*file_io_, metadata_location));
583597
return Table::Make(identifier, std::move(metadata), std::move(metadata_location),
584-
file_io_, shared_from_this());
598+
file_io_, shared_from_this(),
599+
CatalogUtil::FullTableName(name(), identifier), reporter_);
585600
}
586601

587602
Result<std::shared_ptr<Table>> InMemoryCatalog::RegisterTable(
@@ -601,7 +616,8 @@ Result<std::shared_ptr<Table>> InMemoryCatalog::RegisterTable(
601616
return UnknownError("The registry failed.");
602617
}
603618
return Table::Make(identifier, std::move(metadata), metadata_file_location, file_io_,
604-
shared_from_this());
619+
shared_from_this(), CatalogUtil::FullTableName(name(), identifier),
620+
reporter_);
605621
}
606622

607623
} // namespace iceberg

src/iceberg/catalog/memory/in_memory_catalog.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
/// \file iceberg/catalog/memory/in_memory_catalog.h
2323
/// \brief Provide an in-memory catalog implementation.
2424

25+
#include <memory>
2526
#include <shared_mutex>
2627

2728
#include "iceberg/catalog.h"
@@ -42,12 +43,13 @@ class ICEBERG_EXPORT InMemoryCatalog
4243
: public Catalog,
4344
public std::enable_shared_from_this<InMemoryCatalog> {
4445
public:
45-
InMemoryCatalog(std::string const& name, std::shared_ptr<FileIO> const& file_io,
46-
std::string const& warehouse_location,
47-
std::unordered_map<std::string, std::string> const& properties);
46+
InMemoryCatalog(std::string name, std::shared_ptr<FileIO> file_io,
47+
std::string warehouse_location,
48+
std::unordered_map<std::string, std::string> properties,
49+
std::shared_ptr<MetricsReporter> reporter = nullptr);
4850
~InMemoryCatalog() override;
4951

50-
static std::shared_ptr<InMemoryCatalog> Make(
52+
static Result<std::shared_ptr<InMemoryCatalog>> Make(
5153
std::string const& name, std::shared_ptr<FileIO> const& file_io,
5254
std::string const& warehouse_location,
5355
std::unordered_map<std::string, std::string> const& properties);
@@ -109,6 +111,7 @@ class ICEBERG_EXPORT InMemoryCatalog
109111
std::string warehouse_location_;
110112
std::unique_ptr<class InMemoryNamespace> root_namespace_;
111113
mutable std::shared_mutex mutex_;
114+
std::shared_ptr<MetricsReporter> reporter_;
112115
};
113116

114117
} // namespace iceberg

src/iceberg/catalog/meson.build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
subdir('memory')
1919

2020
install_headers(
21-
['session_catalog.h', 'session_context.h'],
21+
['catalog_util.h', 'session_catalog.h', 'session_context.h'],
2222
subdir: 'iceberg/catalog',
2323
)
2424

src/iceberg/catalog/rest/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ set(ICEBERG_REST_SOURCES
3333
resource_paths.cc
3434
rest_catalog.cc
3535
rest_file_io.cc
36+
rest_metrics_reporter.cc
3637
rest_util.cc
3738
types.cc)
3839

src/iceberg/catalog/rest/catalog_properties.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ class ICEBERG_REST_EXPORT RestCatalogProperties
5555
inline static Entry<std::string> kNamespaceSeparator{"namespace-separator", "%1F"};
5656
/// \brief The snapshot loading mode (ALL or REFS).
5757
inline static Entry<std::string> kSnapshotLoadingMode{"snapshot-loading-mode", "ALL"};
58+
/// \brief Whether to report metrics to the REST catalog server (default: true).
59+
inline static Entry<std::string> kMetricsReportingEnabled{
60+
"rest-metrics-reporting-enabled", "true"};
5861
/// \brief The prefix for HTTP headers.
5962
inline static constexpr std::string_view kHeaderPrefix = "header.";
6063

src/iceberg/catalog/rest/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ iceberg_rest_sources = files(
3030
'resource_paths.cc',
3131
'rest_catalog.cc',
3232
'rest_file_io.cc',
33+
'rest_metrics_reporter.cc',
3334
'rest_util.cc',
3435
'types.cc',
3536
)

0 commit comments

Comments
 (0)