Skip to content

Commit 99007f5

Browse files
author
Innocent
committed
feat: metrics reporting for scan and commit
1 parent 743c318 commit 99007f5

23 files changed

Lines changed: 2396 additions & 0 deletions

src/iceberg/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ set(ICEBERG_SOURCES
5858
manifest/v3_metadata.cc
5959
metadata_columns.cc
6060
metrics_config.cc
61+
metrics/commit_report.cc
62+
metrics/counter.cc
63+
metrics/json_serde.cc
64+
metrics/metrics_context.cc
65+
metrics/metrics_reporters.cc
66+
metrics/scan_report.cc
67+
metrics/timer.cc
6168
name_mapping.cc
6269
partition_field.cc
6370
partition_spec.cc
@@ -172,6 +179,7 @@ add_subdirectory(puffin)
172179
add_subdirectory(row)
173180
add_subdirectory(update)
174181
add_subdirectory(util)
182+
add_subdirectory(metrics)
175183

176184
if(ICEBERG_BUILD_BUNDLE)
177185
set(ICEBERG_BUNDLE_SOURCES

src/iceberg/constants.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ namespace iceberg {
3333
constexpr std::string_view kParquetFieldIdKey = "PARQUET:field_id";
3434
constexpr int64_t kInvalidSnapshotId = -1;
3535
constexpr int64_t kInvalidSequenceNumber = -1;
36+
constexpr int64_t kInvalidSchemaId = -1;
3637
/// \brief Stand-in for the current sequence number that will be assigned when the commit
3738
/// is successful. This is replaced when writing a manifest list by the ManifestFile
3839
/// adapter.

src/iceberg/meson.build

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,13 @@ iceberg_sources = files(
7575
'manifest/v2_metadata.cc',
7676
'manifest/v3_metadata.cc',
7777
'metadata_columns.cc',
78+
'metrics/commit_report.cc',
79+
'metrics/counter.cc',
80+
'metrics/json_serde.cc',
81+
'metrics/metrics_context.cc',
82+
'metrics/metrics_reporters.cc',
83+
'metrics/scan_report.cc',
84+
'metrics/timer.cc',
7885
'metrics_config.cc',
7986
'name_mapping.cc',
8087
'partition_field.cc',

src/iceberg/metrics/CMakeLists.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
18+
iceberg_install_all_headers(iceberg/metrics)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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/metrics/commit_report.h"
21+
22+
namespace iceberg {
23+
24+
CommitMetrics CommitMetrics::Of(MetricsContext& context) {
25+
CommitMetrics m;
26+
m.total_duration = context.GetTimer("totalDuration");
27+
m.attempts = context.GetCounter("attempts");
28+
return m;
29+
}
30+
31+
CommitMetrics CommitMetrics::Noop() { return CommitMetrics::Of(MetricsContext::Null()); }
32+
33+
void CommitMetrics::PopulateResult(CommitMetricsResult& result) const {
34+
result.total_duration = total_duration ? TimerResult{total_duration->Count(),
35+
total_duration->TotalDuration()}
36+
: TimerResult{};
37+
result.attempts = attempts ? attempts->Value() : 0;
38+
}
39+
40+
} // namespace iceberg
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
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 <cstdint>
23+
#include <memory>
24+
#include <string>
25+
#include <unordered_map>
26+
27+
#include "iceberg/constants.h"
28+
#include "iceberg/iceberg_export.h"
29+
#include "iceberg/metrics/counter.h"
30+
#include "iceberg/metrics/metrics_context.h"
31+
#include "iceberg/metrics/scan_report.h" // TimerResult
32+
#include "iceberg/metrics/timer.h"
33+
34+
namespace iceberg {
35+
36+
/// \brief Immutable snapshot of commit metrics for use in CommitReport.
37+
///
38+
/// Populated by CommitMetrics::ToResult() (for total_duration and attempts) and
39+
/// by parsing snapshot summary fields (for file/record counts).
40+
/// Mirrors org.apache.iceberg.metrics.CommitMetricsResult.
41+
struct ICEBERG_EXPORT CommitMetricsResult {
42+
/// \brief Total wall-clock duration of the commit attempt (count + nanoseconds).
43+
TimerResult total_duration;
44+
/// \brief Number of commit attempts (1 on success without retries).
45+
int64_t attempts = 0;
46+
/// \brief Number of data files added in this commit.
47+
int64_t added_data_files = 0;
48+
/// \brief Number of data files removed in this commit.
49+
int64_t removed_data_files = 0;
50+
/// \brief Total live data files after this commit.
51+
int64_t total_data_files = 0;
52+
/// \brief Number of delete files added in this commit.
53+
int64_t added_delete_files = 0;
54+
/// \brief Equality delete files added.
55+
int64_t added_equality_delete_files = 0;
56+
/// \brief Positional delete files added.
57+
int64_t added_positional_delete_files = 0;
58+
/// \brief Deletion vectors added.
59+
int64_t added_dvs = 0;
60+
/// \brief Positional delete files removed.
61+
int64_t removed_positional_delete_files = 0;
62+
/// \brief Deletion vectors removed.
63+
int64_t removed_dvs = 0;
64+
/// \brief Equality delete files removed.
65+
int64_t removed_equality_delete_files = 0;
66+
/// \brief Number of delete files removed in this commit.
67+
int64_t removed_delete_files = 0;
68+
/// \brief Total live delete files after this commit.
69+
int64_t total_delete_files = 0;
70+
/// \brief Number of records added in this commit.
71+
int64_t added_records = 0;
72+
/// \brief Number of records removed in this commit.
73+
int64_t removed_records = 0;
74+
/// \brief Total live records after this commit.
75+
int64_t total_records = 0;
76+
/// \brief Total byte size of files added.
77+
int64_t added_files_size_bytes = 0;
78+
/// \brief Total byte size of files removed.
79+
int64_t removed_files_size_bytes = 0;
80+
/// \brief Total byte size of all live files after this commit.
81+
int64_t total_files_size_bytes = 0;
82+
/// \brief Positional delete records added.
83+
int64_t added_positional_deletes = 0;
84+
/// \brief Positional delete records removed.
85+
int64_t removed_positional_deletes = 0;
86+
/// \brief Total positional delete records after this commit.
87+
int64_t total_positional_deletes = 0;
88+
/// \brief Equality delete records added.
89+
int64_t added_equality_deletes = 0;
90+
/// \brief Equality delete records removed.
91+
int64_t removed_equality_deletes = 0;
92+
/// \brief Total equality delete records after this commit.
93+
int64_t total_equality_deletes = 0;
94+
/// \brief Manifest files kept unchanged in this commit.
95+
int64_t kept_manifest_count = 0;
96+
/// \brief Manifest files created in this commit.
97+
int64_t created_manifest_count = 0;
98+
/// \brief Manifest files replaced in this commit.
99+
int64_t replaced_manifest_count = 0;
100+
/// \brief Manifest entries processed in this commit.
101+
int64_t processed_manifest_entries_count = 0;
102+
};
103+
104+
/// \brief Live commit metrics collected during a table commit operation.
105+
///
106+
/// Tracks the overall commit duration and retry count. File/record counts come
107+
/// from the snapshot summary after the commit succeeds and are stored separately
108+
/// in CommitMetricsResult.
109+
///
110+
/// Mirrors org.apache.iceberg.metrics.CommitMetrics.
111+
class ICEBERG_EXPORT CommitMetrics {
112+
public:
113+
/// \brief Create a CommitMetrics instance backed by the given MetricsContext.
114+
static CommitMetrics Of(MetricsContext& context);
115+
116+
/// \brief Create a CommitMetrics instance with all-noop timer and counter.
117+
static CommitMetrics Noop();
118+
119+
/// \brief Snapshot timer and counter values into the corresponding fields of result.
120+
///
121+
/// Only total_duration and attempts are written; the caller is responsible for
122+
/// populating the remaining snapshot-summary fields.
123+
void PopulateResult(CommitMetricsResult& result) const;
124+
125+
/// \brief Timer measuring total wall-clock time of the commit call.
126+
std::shared_ptr<Timer> total_duration;
127+
128+
/// \brief Counter for the number of commit attempts (including retries).
129+
std::shared_ptr<Counter> attempts;
130+
};
131+
132+
/// \brief Report generated after a commit operation.
133+
///
134+
/// Contains metrics about the changes made in a commit, including
135+
/// files added/removed and retry information.
136+
struct ICEBERG_EXPORT CommitReport {
137+
/// \brief The fully qualified name of the table that was modified.
138+
std::string table_name;
139+
/// \brief The snapshot ID created by this commit.
140+
int64_t snapshot_id = kInvalidSnapshotId;
141+
/// \brief The sequence number assigned to this commit.
142+
int64_t sequence_number = kInvalidSequenceNumber;
143+
/// \brief The operation that was performed (append, overwrite, delete, etc.).
144+
std::string operation;
145+
/// \brief Metrics collected during the commit operation.
146+
CommitMetricsResult commit_metrics;
147+
/// \brief Additional key-value metadata.
148+
std::unordered_map<std::string, std::string> metadata;
149+
};
150+
151+
} // namespace iceberg

src/iceberg/metrics/counter.cc

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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/metrics/counter.h"
21+
22+
namespace iceberg {
23+
24+
namespace {
25+
26+
class NoopCounter final : public Counter {
27+
public:
28+
void Increment() override {}
29+
void Increment(int64_t) override {}
30+
int64_t Value() const override { return 0; }
31+
bool IsNoop() const override { return true; }
32+
};
33+
34+
} // namespace
35+
36+
Counter& Counter::Noop() {
37+
static NoopCounter instance;
38+
return instance;
39+
}
40+
41+
DefaultCounter::DefaultCounter(CounterUnit unit) : unit_(unit) {}
42+
43+
void DefaultCounter::Increment() { count_.fetch_add(1, std::memory_order_relaxed); }
44+
45+
void DefaultCounter::Increment(int64_t amount) {
46+
count_.fetch_add(amount, std::memory_order_relaxed);
47+
}
48+
49+
int64_t DefaultCounter::Value() const { return count_.load(std::memory_order_relaxed); }
50+
51+
} // namespace iceberg

0 commit comments

Comments
 (0)