Skip to content

Commit 5fe06c8

Browse files
authored
Merge branch '9.2' into backport/9.2/pr-138046
2 parents c36b47c + a0a3ded commit 5fe06c8

File tree

80 files changed

+1330
-196
lines changed

Some content is hidden

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

80 files changed

+1330
-196
lines changed

docs/changelog/137702.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 137702
2+
summary: Handle index deletion while querying in ES|QL
3+
area: ES|QL
4+
type: bug
5+
issues:
6+
- 135863

docs/changelog/137992.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 137992
2+
summary: Prevent passing a pipeline to a logs stream bulk index request body
3+
area: Data streams
4+
type: bug
5+
issues: []

docs/changelog/138132.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 138132
2+
summary: Fix integer overflow in block memory estimation
3+
area: ES|QL
4+
type: bug
5+
issues: []

docs/reference/search-connectors/release-notes.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,26 @@ If you are an Enterprise Search user and want to upgrade to Elastic 9.0, refer t
1313
It includes detailed steps, tooling, and resources to help you transition to supported alternatives in 9.x, such as Elasticsearch, the Open Web Crawler, and self-managed connectors.
1414
:::
1515

16+
## 9.2.1 [connectors-9.2.1-release-notes]
17+
There are no new features, enhancements, fixes, known issues, or deprecations associated with this release.
18+
1619
## 9.2.0 [connectors-9.2.0-release-notes]
1720

1821
### Features and enhancements [connectors-9.2.0-features-enhancements]
1922
* Refactored pagination from OFFSET-based to keyset (primary-key) pagination in the MySQL connector. This delivers 3×+ faster syncs on large tables and modest gains on smaller ones. [#3719](https://github.com/elastic/connectors/pull/3719).
2023

2124
* Updated the Jira connector to use the new `/rest/api/3/search/jql` endpoint, ensuring compatibility with Jira’s latest API. [#3710](https://github.com/elastic/connectors/pull/3710).
2225

26+
## 9.1.7 [connectors-9.1.7-release-notes]
27+
There are no new features, enhancements, fixes, known issues, or deprecations associated with this release.
28+
29+
## 9.1.6 [connectors-9.1.6-release-notes]
30+
31+
### Features and enhancements [connectors-9.1.6-features-enhancements]
32+
* Idle Github connectors no longer excessively query set-up repositories, which reduces the number of calls to GitHub each connector makes and makes users less likely to hit GitHub API quotas. [#3708](https://github.com/elastic/connectors/pull/3708)
33+
34+
* In the Sharepoint Online connector, /contentstorage/ URLs are no longer synced. [#3630](https://github.com/elastic/connectors/pull/3630)
35+
2336
## 9.1.5 [connectors-9.1.5-release-notes]
2437

2538
### Features and enhancements [connectors-9.1.5-features-enhancements]

docs/release-notes/breaking-changes.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,37 @@ If you are migrating from a version prior to version 9.0, you must first upgrade
1212

1313
% ## Next version [elasticsearch-nextversion-breaking-changes]
1414

15+
## 9.2.1 [elasticsearch-9.2.1-breaking-changes]
16+
17+
There are no breaking changes associated with this release.
18+
19+
## 9.1.7 [elasticsearch-9.1.7-breaking-changes]
20+
21+
There are no breaking changes associated with this release.
22+
23+
## 9.1.6 [elasticsearch-9.1.6-breaking-changes]
24+
25+
There are no breaking changes associated with this release.
26+
27+
## 9.2.0 [elasticsearch-9.2.0-breaking-changes]
28+
29+
Ingest Node:
30+
* Simulate API: Return 400 on invalid processor(s) [#130325](https://github.com/elastic/elasticsearch/pull/130325) (issue: [#120731](https://github.com/elastic/elasticsearch/issues/120731))
31+
32+
Mapping:
33+
* Don't enable norms for fields of type text when the index mode is LogsDB or TSDB [#131317](https://github.com/elastic/elasticsearch/pull/131317)
34+
35+
Vector Search:
36+
* Enable `exclude_source_vectors` by default for new indices [#131907](https://github.com/elastic/elasticsearch/pull/131907)
37+
38+
## 9.0.8 [elasticsearch-9.0.8-breaking-changes]
39+
40+
There are no breaking changes associated with this release.
41+
42+
## 9.1.5 [elasticsearch-9.1.5-breaking-changes]
43+
44+
There are no breaking changes associated with this release.
45+
1546
## 9.1.4 [elasticsearch-9.1.4-breaking-changes]
1647

1748
There are no breaking changes associated with this release.

docs/release-notes/deprecations.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,31 @@ To give you insight into what deprecated features you’re using, {{es}}:
1616

1717
% ## Next version [elasticsearch-nextversion-deprecations]
1818

19+
## 9.1.7 [elasticsearch-9.1.7-deprecations]
20+
21+
There are no deprecations associated with this release.
22+
23+
## 9.2.1 [elasticsearch-9.2.1-deprecations]
24+
25+
There are no deprecations associated with this release.
26+
27+
## 9.1.6 [elasticsearch-9.1.6-deprecations]
28+
29+
There are no deprecations associated with this release.
30+
31+
## 9.2.0 [elasticsearch-9.2.0-deprecations]
32+
33+
Cluster Coordination:
34+
* Remove `PeerFinder` request timeout [#134365](https://github.com/elastic/elasticsearch/pull/134365)
35+
36+
## 9.0.8 [elasticsearch-9.0.8-deprecations]
37+
38+
There are no deprecations associated with this release.
39+
40+
## 9.1.5 [elasticsearch-9.1.5-deprecations]
41+
42+
There are no deprecations associated with this release.
43+
1944
## 9.1.4 [elasticsearch-9.1.4-deprecations]
2045

2146
There are no deprecations associated with this release.

docs/release-notes/index.md

Lines changed: 808 additions & 1 deletion
Large diffs are not rendered by default.

modules/apm/src/main/java/org/elasticsearch/telemetry/apm/internal/tracing/APMTracer.java

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,9 @@ public void startTrace(TraceContext traceContext, Traceable traceable, String sp
177177

178178
// A span can have a parent span, which here is modelled though a parent span context.
179179
// Setting this is important for seeing a complete trace in the APM UI.
180-
final Context parentContext = getParentContext(traceContext);
180+
// Attempt to fetch a local parent context first, otherwise look for a remote parent
181+
final Context localParentContext = traceContext.getTransient(Task.PARENT_APM_TRACE_CONTEXT);
182+
final Context parentContext = localParentContext != null ? localParentContext : getRemoteParentContext(traceContext);
181183
if (parentContext != null) {
182184
spanBuilder.setParent(parentContext);
183185
}
@@ -188,21 +190,21 @@ public void startTrace(TraceContext traceContext, Traceable traceable, String sp
188190
if (startTime != null) {
189191
spanBuilder.setStartTimestamp(startTime);
190192
}
193+
191194
final Span span = spanBuilder.startSpan();
192-
// If the agent decided not to record this span (e.g., due to transaction_max_spans), isRecording() will be false.
193-
if (span.isRecording() == false) {
194-
logger.trace("Span [{}] [{}] will not be recorded, e.g. due to transaction_max_spans reached", spanId, spanName);
195-
// It's good practice to end the no-op span immediately to release any resources.
196-
span.end();
197-
// Returning null from computeIfAbsent means no value will be inserted into the map.
198-
return null;
195+
// If not a root span (meaning a local parent exists) and the agent decided not to record the span, discard it immediately.
196+
// Root spans (transactions), however, have to be kept to correctly report their duration.
197+
if (localParentContext != null && span.isRecording() == false) {
198+
logger.trace("Span [{}] [{}] will not be recorded due to transaction_max_spans reached", spanId, spanName);
199+
span.end(); // end span immediately to release any resources.
200+
return null; // return null to discard and not record in map of spans
199201
}
200202

201-
// If we are here, the span is real and being recorded.
202-
logger.trace("Successfully started tracing [{}] [{}]", spanId, spanName);
203203
final Context contextForNewSpan = Context.current().with(span);
204-
205-
updateThreadContext(traceContext, services, contextForNewSpan);
204+
if (span.isRecording()) {
205+
logger.trace("Recording trace [{}] [{}]", spanId, spanName);
206+
updateThreadContext(traceContext, services, contextForNewSpan);
207+
}
206208

207209
return contextForNewSpan;
208210
});
@@ -240,30 +242,26 @@ private static void updateThreadContext(TraceContext traceContext, APMServices s
240242
});
241243
}
242244

243-
private Context getParentContext(TraceContext traceContext) {
245+
private Context getRemoteParentContext(TraceContext traceContext) {
244246
// https://github.com/open-telemetry/opentelemetry-java/discussions/2884#discussioncomment-381870
245247
// If you just want to propagate across threads within the same process, you don't need context propagators (extract/inject).
246248
// You can just pass the Context object directly to another thread (it is immutable and thus thread-safe).
247249

248-
// Attempt to fetch a local parent context first, otherwise look for a remote parent
249-
Context parentContext = traceContext.getTransient(Task.PARENT_APM_TRACE_CONTEXT);
250-
if (parentContext == null) {
251-
final String traceParentHeader = traceContext.getTransient(Task.PARENT_TRACE_PARENT_HEADER);
252-
final String traceStateHeader = traceContext.getTransient(Task.PARENT_TRACE_STATE);
253-
254-
if (traceParentHeader != null) {
255-
final Map<String, String> traceContextMap = Maps.newMapWithExpectedSize(2);
256-
// traceparent and tracestate should match the keys used by W3CTraceContextPropagator
257-
traceContextMap.put(Task.TRACE_PARENT_HTTP_HEADER, traceParentHeader);
258-
if (traceStateHeader != null) {
259-
traceContextMap.put(Task.TRACE_STATE, traceStateHeader);
260-
}
261-
parentContext = services.openTelemetry.getPropagators()
262-
.getTextMapPropagator()
263-
.extract(Context.current(), traceContextMap, new MapKeyGetter());
250+
final String traceParentHeader = traceContext.getTransient(Task.PARENT_TRACE_PARENT_HEADER);
251+
final String traceStateHeader = traceContext.getTransient(Task.PARENT_TRACE_STATE);
252+
253+
if (traceParentHeader != null) {
254+
final Map<String, String> traceContextMap = Maps.newMapWithExpectedSize(2);
255+
// traceparent and tracestate should match the keys used by W3CTraceContextPropagator
256+
traceContextMap.put(Task.TRACE_PARENT_HTTP_HEADER, traceParentHeader);
257+
if (traceStateHeader != null) {
258+
traceContextMap.put(Task.TRACE_STATE, traceStateHeader);
264259
}
260+
return services.openTelemetry.getPropagators()
261+
.getTextMapPropagator()
262+
.extract(Context.current(), traceContextMap, new MapKeyGetter());
265263
}
266-
return parentContext;
264+
return null;
267265
}
268266

269267
/**
@@ -288,7 +286,7 @@ private Context getParentContext(TraceContext traceContext) {
288286
@Override
289287
public Releasable withScope(Traceable traceable) {
290288
final Context context = spans.get(traceable.getSpanId());
291-
if (context != null) {
289+
if (context != null && Span.fromContextOrNull(context).isRecording()) {
292290
return context.makeCurrent()::close;
293291
}
294292
return () -> {};
@@ -385,9 +383,10 @@ public void setAttribute(Traceable traceable, String key, String value) {
385383

386384
@Override
387385
public void stopTrace(Traceable traceable) {
388-
final var span = Span.fromContextOrNull(spans.remove(traceable.getSpanId()));
386+
final String spanId = traceable.getSpanId();
387+
final var span = Span.fromContextOrNull(spans.remove(spanId));
389388
if (span != null) {
390-
logger.trace("Finishing trace [{}]", traceable);
389+
logger.trace("Finishing trace [{}]", spanId);
391390
span.end();
392391
}
393392
}

modules/apm/src/test/java/org/elasticsearch/telemetry/apm/internal/tracing/APMTracerTests.java

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.elasticsearch.common.util.concurrent.ThreadContext;
2424
import org.elasticsearch.tasks.Task;
2525
import org.elasticsearch.telemetry.apm.internal.APMAgentSettings;
26+
import org.elasticsearch.telemetry.tracing.TraceContext;
2627
import org.elasticsearch.telemetry.tracing.Traceable;
2728
import org.elasticsearch.test.ESTestCase;
2829
import org.elasticsearch.test.junit.annotations.TestLogging;
@@ -42,6 +43,7 @@
4243
import static org.hamcrest.Matchers.is;
4344
import static org.hamcrest.Matchers.not;
4445
import static org.hamcrest.Matchers.notNullValue;
46+
import static org.hamcrest.Matchers.nullValue;
4547
import static org.mockito.ArgumentMatchers.anyString;
4648
import static org.mockito.Mockito.doAnswer;
4749
import static org.mockito.Mockito.mock;
@@ -87,22 +89,29 @@ public void test_onTraceStarted_startsTrace() {
8789
Settings settings = Settings.builder().put(APMAgentSettings.TELEMETRY_TRACING_ENABLED_SETTING.getKey(), true).build();
8890
APMTracer apmTracer = buildTracer(settings);
8991

90-
apmTracer.startTrace(new ThreadContext(settings), TRACEABLE1, "name1", null);
92+
ThreadContext traceContext = new ThreadContext(settings);
93+
apmTracer.startTrace(traceContext, TRACEABLE1, "name1", null);
9194

95+
assertThat(traceContext.getTransient(Task.APM_TRACE_CONTEXT), notNullValue());
9296
assertThat(apmTracer.getSpans(), aMapWithSize(1));
9397
assertThat(apmTracer.getSpans(), hasKey(TRACEABLE1.getSpanId()));
9498
}
9599

96100
/**
97-
* Check that when a trace is started, but it is not recorded, e.g. due to sampling, the tracer does not record it either.
101+
* Check that when a root trace is started, but it is not recorded, e.g. due to sampling,
102+
* the tracer tracks it but doesn't start tracing.
98103
*/
99-
public void test_onTraceStarted_ifNotRecorded_doesNotStartTrace() {
104+
public void test_onTraceStarted_ifNotRecorded_doesNotStartTracing() {
100105
Settings settings = Settings.builder().put(APMAgentSettings.TELEMETRY_TRACING_ENABLED_SETTING.getKey(), true).build();
101106
APMTracer apmTracer = buildTracer(settings);
102107

103-
apmTracer.startTrace(new ThreadContext(settings), TRACEABLE1, "name1_discard", null);
108+
ThreadContext traceContext = new ThreadContext(settings);
109+
apmTracer.startTrace(traceContext, TRACEABLE1, "name1_discard", null);
104110

105-
assertThat(apmTracer.getSpans(), anEmptyMap());
111+
assertThat(traceContext.getTransient(Task.APM_TRACE_CONTEXT), nullValue());
112+
// the root span (transaction) is tracked
113+
assertThat(apmTracer.getSpans(), aMapWithSize(1));
114+
assertThat(apmTracer.getSpans(), hasKey(TRACEABLE1.getSpanId()));
106115
}
107116

108117
/**
@@ -116,8 +125,11 @@ public void test_onNestedTraceStarted_ifNotRecorded_doesNotStartTrace() {
116125
apmTracer.startTrace(traceContext, TRACEABLE1, "name1", null);
117126
try (var ignore1 = traceContext.newTraceContext()) {
118127
apmTracer.startTrace(traceContext, TRACEABLE2, "name2_discard", null);
128+
assertThat(traceContext.getTransient(Task.APM_TRACE_CONTEXT), nullValue());
129+
119130
try (var ignore2 = traceContext.newTraceContext()) {
120131
apmTracer.startTrace(traceContext, TRACEABLE3, "name3_discard", null);
132+
assertThat(traceContext.getTransient(Task.APM_TRACE_CONTEXT), nullValue());
121133
}
122134
}
123135
assertThat(apmTracer.getSpans(), aMapWithSize(1));
@@ -131,12 +143,13 @@ public void test_onTraceStartedWithStartTime_startsTrace() {
131143
Settings settings = Settings.builder().put(APMAgentSettings.TELEMETRY_TRACING_ENABLED_SETTING.getKey(), true).build();
132144
APMTracer apmTracer = buildTracer(settings);
133145

134-
ThreadContext threadContext = new ThreadContext(settings);
146+
TraceContext traceContext = new ThreadContext(settings);
135147
// 1_000_000L because of "toNanos" conversions that overflow for large long millis
136148
Instant spanStartTime = Instant.ofEpochMilli(randomLongBetween(0, Long.MAX_VALUE / 1_000_000L));
137-
threadContext.putTransient(Task.TRACE_START_TIME, spanStartTime);
138-
apmTracer.startTrace(threadContext, TRACEABLE1, "name1", null);
149+
traceContext.putTransient(Task.TRACE_START_TIME, spanStartTime);
150+
apmTracer.startTrace(traceContext, TRACEABLE1, "name1", null);
139151

152+
assertThat(traceContext.getTransient(Task.APM_TRACE_CONTEXT), notNullValue());
140153
assertThat(apmTracer.getSpans(), aMapWithSize(1));
141154
assertThat(apmTracer.getSpans(), hasKey(TRACEABLE1.getSpanId()));
142155
assertThat(((SpyAPMTracer) apmTracer).getSpanStartTime("name1"), is(spanStartTime));
@@ -151,6 +164,7 @@ public void test_onTraceStopped_stopsTrace() {
151164

152165
apmTracer.startTrace(new ThreadContext(settings), TRACEABLE1, "name1", null);
153166
apmTracer.stopTrace(TRACEABLE1);
167+
apmTracer.stopTrace(TRACEABLE2); // stopping a non-existent trace is a noop
154168

155169
assertThat(apmTracer.getSpans(), anEmptyMap());
156170
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
teardown:
3+
- do:
4+
streams.logs_disable: { }
5+
6+
---
7+
"Check User Can't Provide Pipeline to Logs Stream":
8+
- do:
9+
streams.logs_enable: { }
10+
- is_true: acknowledged
11+
12+
- do:
13+
streams.status: { }
14+
- is_true: logs.enabled
15+
16+
- do:
17+
bulk:
18+
index: logs
19+
body: |
20+
{ "create": {"pipeline": "noop"}}
21+
{ "message": "hello streams!"}
22+
- match: { errors: true }
23+
- match: { items.0.create.status: 400 }
24+
- match: { items.0.create.error.type: "illegal_argument_exception" }
25+
- match: { items.0.create.error.reason: "Cannot provide a pipeline when writing to a stream however the [noop] pipeline was provided when writing to the [logs] stream" }

0 commit comments

Comments
 (0)