Skip to content
Open
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
66dfb39
create project skeleton
ghareeb-falazi Oct 22, 2025
cfa5695
import correct iceberg library
ghareeb-falazi Oct 22, 2025
caca4af
initial ScanMetrics builders implementation
ghareeb-falazi Oct 23, 2025
e56fb2e
apply spotless
ghareeb-falazi Oct 23, 2025
b200b65
Merge branch 'open-telemetry:main' into main
ghareeb-falazi Oct 24, 2025
d900bd4
update iceberg version
ghareeb-falazi Oct 24, 2025
1359cf5
Merge branch 'open-telemetry:main' into main
ghareeb-falazi Oct 30, 2025
ad6c673
fix some build issues
ghareeb-falazi Oct 30, 2025
c5ca17e
Merge branch 'main' of github.com:ghareeb-falazi/opentelemetry-java-i…
ghareeb-falazi Oct 30, 2025
5d94635
Convert DoubleGauge to LongGauge
ghareeb-falazi Oct 30, 2025
b8acfe8
Convert LongGauge to LongCounter
ghareeb-falazi Oct 30, 2025
77dd606
add attributes to scan metrics
ghareeb-falazi Oct 30, 2025
b7a4b5d
create commit metrics builder
ghareeb-falazi Oct 30, 2025
98ee412
Finalize IcebergMetricsReporter implementation
ghareeb-falazi Oct 31, 2025
b912f8f
initial testing implementation
ghareeb-falazi Nov 3, 2025
9498d36
finish implementing unit test
ghareeb-falazi Nov 4, 2025
a35cf9e
remove commit metrics
ghareeb-falazi Nov 4, 2025
716ae50
Merge branch 'open-telemetry:main' into main
ghareeb-falazi Nov 4, 2025
6a74905
Merge branch 'main' of github.com:ghareeb-falazi/opentelemetry-java-i…
ghareeb-falazi Nov 4, 2025
920dd26
Fix style issue
ghareeb-falazi Nov 4, 2025
6a758b7
reorder imports
ghareeb-falazi Nov 4, 2025
a42c03e
make only class in testing project public to pass javadoc task
ghareeb-falazi Nov 4, 2025
061f58f
set minJavaVersionSupported to 11 since this is required by the Icebe…
ghareeb-falazi Nov 4, 2025
e672e3b
Apply suggestions from code review
ghareeb-falazi Nov 4, 2025
af1dd70
apply suggestions from code review
ghareeb-falazi Nov 4, 2025
570aa7c
Merge branch 'main' of github.com:ghareeb-falazi/opentelemetry-java-i…
ghareeb-falazi Nov 4, 2025
8d975b9
reorder imports
ghareeb-falazi Nov 4, 2025
93d9380
Merge branch 'main' into main
ghareeb-falazi Nov 4, 2025
e64d52d
Merge branch 'main' into main
ghareeb-falazi Nov 6, 2025
1dd3179
Merge branch 'main' into main
ghareeb-falazi Nov 10, 2025
62b4f02
Merge branch 'main' into main
ghareeb-falazi Nov 11, 2025
e9aeabe
apply review comments
ghareeb-falazi Nov 13, 2025
2bcd4bc
Merge branch 'main' into main
ghareeb-falazi Nov 13, 2025
daba240
Merge branch 'main' into main
ghareeb-falazi Nov 14, 2025
65aaf61
Merge branch 'main' into main
ghareeb-falazi Nov 17, 2025
ef2ae85
Merge branch 'main' into main
ghareeb-falazi Nov 21, 2025
6f8e403
merge metrics
ghareeb-falazi Nov 21, 2025
088e2dd
adapt unit tests to new metrics
ghareeb-falazi Nov 21, 2025
2cb4f4f
Merge branch 'main' into main
ghareeb-falazi Nov 21, 2025
ea200d3
limit java version for tests to 17 to allow hadoop to run
ghareeb-falazi Nov 22, 2025
978aa55
Merge branch 'main' of github.com:ghareeb-falazi/opentelemetry-java-i…
ghareeb-falazi Nov 22, 2025
d7f72ef
add javadocs to the public class
ghareeb-falazi Nov 22, 2025
f5d96e3
apply advice to exclude snapshot_id attribute
ghareeb-falazi Nov 22, 2025
90f5047
try unit tests with java 21
ghareeb-falazi Nov 22, 2025
752cf4b
Merge branch 'main' into main
ghareeb-falazi Nov 24, 2025
0b0a161
revert to using iceberg's TestTables in unit tests to ensure we can t…
ghareeb-falazi Nov 26, 2025
308f819
Merge branch 'main' into main
ghareeb-falazi Nov 26, 2025
b6ee75e
Merge branch 'main' into main
ghareeb-falazi Nov 27, 2025
aee6f7b
Update comment in instrumentation/iceberg-1.8/testing/build.gradle.kts
ghareeb-falazi Nov 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .fossa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ targets:
- type: gradle
path: ./
target: ':instrumentation:hystrix-1.4:javaagent'
- type: gradle
path: ./
target: ':instrumentation:iceberg-1.8:library'
- type: gradle
path: ./
target: ':instrumentation:influxdb-2.4:javaagent'
Expand Down
43 changes: 43 additions & 0 deletions instrumentation/iceberg-1.8/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Library Instrumentation for Apache Iceberg Version 1.8 and Higher

Provides OpenTelemetry instrumentation for [Apache Iceberg](https://iceberg.apache.org/).

## Quickstart

### Add These Dependencies to Your Project

Replace `OPENTELEMETRY_VERSION` with the [latest release](https://central.sonatype.com/artifact/io.opentelemetry.instrumentation/opentelemetry-iceberg-1.8).

For Maven, add to your `pom.xml` dependencies:

```xml
<dependencies>
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-iceberg-1.8</artifactId>
<version>OPENTELEMETRY_VERSION</version>
</dependency>
</dependencies>
```

For Gradle, add to your dependencies:

```groovy
implementation("io.opentelemetry.instrumentation:opentelemetry-iceberg-1.8:OPENTELEMETRY_VERSION")
```

### Usage

The instrumentation library allows creating instrumented `Scan` (e.g., `TableScan`) instances for collecting and reporting OpenTelemetry-based sacn metrics. For example:

```java
OpenTelemetry openTelemetry = // ...
IcebergTelemetry icebergTelemetry = IcebergTelemetry.create(openTelemetry);
TableScan tableScan = icebergTelemetry.wrapScan(table.newScan());

try (CloseableIterable<FileScanTask> fileScanTasks = tableScan.planFiles()) {
// Process the scan tasks
}

// The metrics will be reported after the scan tasks iterable is closed
```
13 changes: 13 additions & 0 deletions instrumentation/iceberg-1.8/library/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
plugins {
id("otel.library-instrumentation")
id("otel.nullaway-conventions")
}

dependencies {
library("org.apache.iceberg:iceberg-core:1.8.1")
testImplementation(project(":instrumentation:iceberg-1.8:testing"))
}

otelJava {
minJavaVersionSupported.set(JavaVersion.VERSION_11)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.iceberg.v1_8;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.api.metrics.LongGauge;
import java.util.Locale;
import org.apache.iceberg.metrics.CounterResult;
import org.apache.iceberg.metrics.MetricsReport;
import org.apache.iceberg.metrics.MetricsReporter;
import org.apache.iceberg.metrics.ScanMetricsResult;
import org.apache.iceberg.metrics.ScanReport;
import org.apache.iceberg.metrics.TimerResult;

public class IcebergMetricsReporter implements MetricsReporter {
private static final String INSTRUMENTATION_NAME = "io.opentelemetry.iceberg_1.8";
private static final AttributeKey<Long> SCHEMA_ID = AttributeKey.longKey("iceberg.schema.id");
private static final AttributeKey<String> TABLE_NAME =
AttributeKey.stringKey("iceberg.table.name");
private static final AttributeKey<Long> SNAPHSOT_ID = AttributeKey.longKey("iceberg.snapshot.id");

private final OpenTelemetry openTelemetry;

IcebergMetricsReporter(OpenTelemetry openTelemetry) {
this.openTelemetry = openTelemetry;
}

@Override
public void report(MetricsReport report) {
if (report instanceof ScanReport) {
reportScanMetrics((ScanReport) report);
}
}

void reportScanMetrics(ScanReport scanReport) {
Attributes scanAttributes =
Attributes.of(
SCHEMA_ID,
Long.valueOf(scanReport.schemaId()),
TABLE_NAME,
scanReport.tableName(),
SNAPHSOT_ID,
scanReport.snapshotId());
ScanMetricsResult metrics = scanReport.scanMetrics();
TimerResult duration = metrics.totalPlanningDuration();

if (duration != null) {
LongGauge metric =
ScanMetricsBuilder.totalPlanningDuration(
openTelemetry.getMeter(INSTRUMENTATION_NAME),
duration.timeUnit().name().toLowerCase(Locale.getDefault()));
metric.set(duration.totalDuration().toMillis(), scanAttributes);
}

CounterResult current = metrics.resultDataFiles();

if (current != null) {
LongCounter metric =
ScanMetricsBuilder.scannedDataFilesCount(openTelemetry.getMeter(INSTRUMENTATION_NAME));
metric.add(current.value(), scanAttributes);
}

current = metrics.resultDeleteFiles();

if (current != null) {
LongCounter metric =
ScanMetricsBuilder.scannedDeleteFilesCount(openTelemetry.getMeter(INSTRUMENTATION_NAME));
metric.add(current.value(), scanAttributes);
}

current = metrics.scannedDataManifests();

if (current != null) {
LongCounter metric =
ScanMetricsBuilder.scannedDataManifestsCount(
openTelemetry.getMeter(INSTRUMENTATION_NAME));
metric.add(current.value(), scanAttributes);
}

current = metrics.scannedDeleteManifests();

if (current != null) {
LongCounter metric =
ScanMetricsBuilder.scannedDeleteManifestsCount(
openTelemetry.getMeter(INSTRUMENTATION_NAME));
metric.add(current.value(), scanAttributes);
}

current = metrics.totalDataManifests();

if (current != null) {
LongCounter metric =
ScanMetricsBuilder.totalDataManifestsCount(openTelemetry.getMeter(INSTRUMENTATION_NAME));
metric.add(current.value(), scanAttributes);
}

current = metrics.totalDeleteManifests();

if (current != null) {
LongCounter metric =
ScanMetricsBuilder.totalDeleteManifestsCount(
openTelemetry.getMeter(INSTRUMENTATION_NAME));
metric.add(current.value(), scanAttributes);
}

current = metrics.totalFileSizeInBytes();

if (current != null) {
LongCounter metric =
ScanMetricsBuilder.scannedDataFilesSize(openTelemetry.getMeter(INSTRUMENTATION_NAME));
metric.add(current.value(), scanAttributes);
}

current = metrics.totalDeleteFileSizeInBytes();

if (current != null) {
LongCounter metric =
ScanMetricsBuilder.scannedDeleteFilesSize(openTelemetry.getMeter(INSTRUMENTATION_NAME));
metric.add(current.value(), scanAttributes);
}

current = metrics.skippedDataManifests();

if (current != null) {
LongCounter metric =
ScanMetricsBuilder.skippedDataManifestsCount(
openTelemetry.getMeter(INSTRUMENTATION_NAME));
metric.add(current.value(), scanAttributes);
}

current = metrics.skippedDeleteManifests();

if (current != null) {
LongCounter metric =
ScanMetricsBuilder.skippedDeleteManifestsCount(
openTelemetry.getMeter(INSTRUMENTATION_NAME));
metric.add(current.value(), scanAttributes);
}

current = metrics.skippedDataFiles();

if (current != null) {
LongCounter metric =
ScanMetricsBuilder.skippedDataFilesCount(openTelemetry.getMeter(INSTRUMENTATION_NAME));
metric.add(current.value(), scanAttributes);
}

current = metrics.skippedDeleteFiles();

if (current != null) {
LongCounter metric =
ScanMetricsBuilder.skippedDeleteFilesCount(openTelemetry.getMeter(INSTRUMENTATION_NAME));
metric.add(current.value(), scanAttributes);
}

current = metrics.indexedDeleteFiles();

if (current != null) {
LongCounter metric =
ScanMetricsBuilder.indexedDeleteFilesCount(openTelemetry.getMeter(INSTRUMENTATION_NAME));
metric.add(current.value(), scanAttributes);
}

current = metrics.equalityDeleteFiles();

if (current != null) {
LongCounter metric =
ScanMetricsBuilder.equalityDeleteFilesCount(openTelemetry.getMeter(INSTRUMENTATION_NAME));
metric.add(current.value(), scanAttributes);
}

current = metrics.positionalDeleteFiles();

if (current != null) {
LongCounter metric =
ScanMetricsBuilder.positionDeleteFilesCount(openTelemetry.getMeter(INSTRUMENTATION_NAME));
metric.add(current.value(), scanAttributes);
}

current = metrics.dvs();

if (current != null) {
LongCounter metric =
ScanMetricsBuilder.deletionVectorFilesCount(openTelemetry.getMeter(INSTRUMENTATION_NAME));
metric.add(current.value(), scanAttributes);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.iceberg.v1_8;

import io.opentelemetry.api.OpenTelemetry;
import org.apache.iceberg.Scan;
import org.apache.iceberg.ScanTask;
import org.apache.iceberg.ScanTaskGroup;

public class IcebergTelemetry {
private final OpenTelemetry openTelemetry;

public static IcebergTelemetry create(OpenTelemetry openTelemetry) {
return new IcebergTelemetry(openTelemetry);
}

IcebergTelemetry(OpenTelemetry openTelemetry) {
this.openTelemetry = openTelemetry;
}

public <T1, T2 extends ScanTask, T3 extends ScanTaskGroup<T2>> T1 wrapScan(
Scan<T1, T2, T3> scan) {
return scan.metricsReporter(new IcebergMetricsReporter(openTelemetry));
}
}
Loading
Loading