Skip to content

Commit

Permalink
Merge branch 'dev' into master-hotfix
Browse files Browse the repository at this point in the history
  • Loading branch information
novoj committed Feb 11, 2025
2 parents bceb1af + baf18d8 commit dfed823
Show file tree
Hide file tree
Showing 78 changed files with 831 additions and 240 deletions.
4 changes: 2 additions & 2 deletions .github/release-drafter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ latest: 'true'
prerelease: true
prerelease-identifier: 'beta'
categories:
- title: '⁉️ Breaking changes'
- title: '⛓️‍💥 Breaking changes'
labels:
- 'breaking change'
- 'breaking'
Expand All @@ -28,7 +28,7 @@ autolabeler:
- label: 'bug'
title:
- '/^fix(\(.*\))?:/'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)<br/>$BODY'
change-template: '- **$TITLE** @$AUTHOR (#$NUMBER)<br/>$BODY'
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
filter-by-commitish: true

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ jobs:
uses: release-drafter/release-drafter@b1476f6e6eb133afa41ed8589daba6dc69b4d3f5 # v6.1.0
with:
version: ${{ steps.release_version.outputs.version }}
publish: true
publish: false
latest: ${{ github.ref_name == 'master' && 'true' || 'legacy' }}

- name: Upload dist.zip to release
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
examples and guides.</p>

<p align="center">
<a href="https://github.com/FgForrest/evitaDB" title="Build"><img src="https://img.shields.io/github/v/release/FgForrest/evitadb?color=%23ff00a0&include_prereleases&label=version&sort=semver"/></a>
<a href="https://github.com/FgForrest/evitaDB/releases" title="Build"><img src="https://img.shields.io/github/v/release/FgForrest/evitadb?color=%23ff00a0&include_prereleases&label=version&sort=semver"/></a>
&nbsp;
<a href="https://codecov.io/gh/FgForrest/evitaDB"><img src="https://codecov.io/gh/FgForrest/evitaDB/branch/dev/graph/badge.svg?token=9VDOBPOBFL"/></a>
&nbsp;
<a href="https://github.com/FgForrest/evitaDB" title="Platform"><img src="https://img.shields.io/badge/Built%20with-Java-red"/></a>
&nbsp;
<a href="https://discord.gg/VsNBWxgmSw" title="Discord"><img src="https://img.shields.io/discord/999338870996992223?color=5865f2"/></a>
&nbsp;
<a href="https://github.com/FgForrest/evitaDB" title="GitHub Workflow Status"><img src="https://img.shields.io/github/actions/workflow/status/FgForrest/evitaDB/ci-dev.yml"/></a>
<a href="https://github.com/FgForrest/evitaDB/actions/workflows/ci-dev.yml" title="GitHub Workflow Status"><img src="https://img.shields.io/github/actions/workflow/status/FgForrest/evitaDB/ci-dev.yml"/></a>
&nbsp;
<a href="https://github.com/FgForrest/evitaDB/blob/master/LICENSE" title="License"><img src="https://img.shields.io/badge/license-BSL_1.1-blue.svg"/></a>
</p>
Expand Down Expand Up @@ -211,6 +211,7 @@ In short, you need `~/.m2/toolchains.xml` in your home directory next to `~/.m2/
- **evita_external_api_graphql**: implementation of GraphQL API
- **evita_external_api_grpc**: implementation of gRPC API
- **client**: Java driver for client/server usage scenario
- **client_all_in_one**: Java driver for client/server usage scenario that includes repackaged all necessary dependencies so that it will not conflict with other dependencies in your project (unfortunately it's quite big due to gRPC and Armeria dependencies)
- **server**: gRPC server
- **shared**: shared classes between client & server (generated gRPC stubs)
- **evita_external_api_rest**: implementation of REST API
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Each code block is then rendered as an individual tab within the `<CodeTabsBlock
<dependency>
<groupId>io.evitadb</groupId>
<artifactId>evita_test_support</artifactId>
<version>2024.10.0</version>
<version>2025.1.0</version>
<scope>test</scope>
</dependency>
```
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,17 @@ author: 'Ing. Jan Novotný'
motive: assets/images/16-traffic-recording.png
proofreading: 'done'
---

In the latest version `2025.1` of evitaDB we have introduced a new feature called `Traffic Recording`. It's disabled by default, but you can easily enable it by setting `server.trafficRecording.enabled` to `true`. Even if you don't do this, you can always start it manually in the evitaLab console. This feature allows you to record all traffic that passes through the database - sessions, queries, mutations, entity fetches - everything.

The capture engine is designed to be as lightweight as possible, so you can run it in production without noticing any performance degradation. If the traffic is heavy, you can also configure the recording engine to sample the traffic, reducing the amount of data stored, but still enough to analyse traffic patterns. Traffic data is serialised in a limited buffer in memory, which is very fast, and then flushed asynchronously to the disk buffer file. If the flushing process can't keep up with the traffic, the recording engine will automatically discard any traffic that doesn't fit into the memory buffer. So the worst-case scenario is that you'll lose some data for analysis, but the database will still work fine and your customers won't notice a thing.
The capture engine is designed to be as lightweight as possible, so that you can run the tool in the production. If the traffic is heavy, you can also configure the recording engine to sample the traffic, reducing the amount of data stored and limit the performance impact, but still enough to analyse traffic patterns. Traffic data is serialised in a limited buffer in memory, which is quite fast, and then flushed asynchronously to the disk buffer file. If the flushing process can't keep up with the traffic, the recording engine will automatically discard any traffic that doesn't fit into the memory buffer. So the worst-case scenario is that you'll lose some data for analysis, but the database will still work fine and your customers won't notice a thing.

<p>
<video width="850" height="478" controls="controls">
<source src="https://evitadb.io/download/blog-16-traffic-recording-1.mp4" type="video/mp4"/>
Your browser does not support the video tag.
</video>
</p>

The disk buffer is designed to behave like a ring buffer and is allocated at the start of the database, so you can't run out of disk space. When the end of the buffer is reached, the recording engine starts to overwrite the oldest data from the beginning. You can start another asynchronous task that will capture all the data from the disk buffer file before it's overwritten into another compressed file for later analysis. This task can be set to stop automatically when it reaches a certain data size or after a certain period of time.

Expand All @@ -23,6 +31,13 @@ With Traffic Recording, evitaDB can be set up to automatically capture all traff

Traffic Recorder captures queries in their original format (GraphQL, REST, gRPC) as well as in the internal evitaQL format. Often a single GraphQL query can represent several evitaQL queries that are combined into a single result and actually executed in parallel by the query engine. All these relationships are captured and visualised in the evitaLab interface. All input queries are available in the exact form in which they arrived in the database, so you can access variables, fragments, etc. as they were sent by the client.

<p>
<video width="850" height="478" controls="controls">
<source src="https://evitadb.io/download/blog-16-traffic-recording-2.mp4" type="video/mp4"/>
Your browser does not support the video tag.
</video>
</p>

The traffic recorder also records all invalid requests, so you can see requests that couldn't be parsed or were rejected by the database for some reason. This can be very useful for debugging and improving the client application.

The filter allows you to filter queries by various criteria - for example, you can filter only queries that took more than a certain amount of time to execute, or only queries that fetched excessive amounts of data from disk. This can help you identify performance bottlenecks in your application early in the development process.
Expand All @@ -31,6 +46,13 @@ The filter allows you to filter queries by various criteria - for example, you c

Because you can capture a representative sample of traffic, you can use it to analyse the performance of your application. You can see which queries are the most frequent, which are the slowest, which are fetching the most data, etc. You can restore backups of your production data and replay the captured traffic on different machines to test different hardware configurations, or stress test the database by increasing the replay speed or multiplying it by parallelizing clients replaying the traffic.

<p>
<video width="850" height="478" controls="controls">
<source src="https://evitadb.io/download/blog-16-traffic-recording-3.mp4" type="video/mp4"/>
Your browser does not support the video tag.
</video>
</p>

This is a very cost effective way of discovering the limits of your application in real-world scenarios on an accurate dataset and making correct assumptions about the performance of your application and the necessary hardware requirements. You can also use traffic recording to compare the performance of different versions of your application or database engine.

## Traffic replay and testing
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
25 changes: 24 additions & 1 deletion documentation/user/en/get-started/example/server-startup.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
/*
*
* _ _ ____ ____
* _____ _(_) |_ __ _| _ \| __ )
* / _ \ \ / / | __/ _` | | | | _ \
* | __/\ V /| | || (_| | |_| | |_) |
* \___| \_/ |_|\__\__,_|____/|____/
*
* Copyright (c) 2025
*
* Licensed under the Business Source License, Version 1.1 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://github.com/FgForrest/evitaDB/blob/master/LICENSE
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

final Evita evita = new Evita(
EvitaConfiguration.builder()
.server(
Expand All @@ -9,7 +32,7 @@
.storage(
// configure additional storage options, or let the defaults apply
StorageOptions.builder()
.storageDirectory(Path.of("/data"))
.storageDirectory(Path.of("./data"))
.build()
)
.cache(
Expand Down
2 changes: 1 addition & 1 deletion documentation/user/en/get-started/query-our-dataset.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ Open your Java IDE and add the following dependency to your project:
<dependency>
<groupId>io.evitadb</groupId>
<artifactId>evita_java_driver</artifactId>
<version>2024.10.0</version>
<version>2025.1.0</version>
</dependency>
```
</CodeTabsBlock>
Expand Down
8 changes: 4 additions & 4 deletions documentation/user/en/get-started/run-evitadb.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ To integrate evitaDB into your project, use the following steps:
<dependency>
<groupId>io.evitadb</groupId>
<artifactId>evita_db</artifactId>
<version>2024.10.0</version>
<version>2025.1.0</version>
<type>pom</type>
</dependency>
```
Expand Down Expand Up @@ -108,7 +108,7 @@ exception when you enable the corresponding API in evitaDB's configuration.
<dependency>
<groupId>io.evitadb</groupId>
<artifactId>evita_external_api_grpc</artifactId>
<version>2024.10.0</version>
<version>2025.1.0</version>
<type>pom</type>
</dependency>
```
Expand All @@ -128,7 +128,7 @@ implementation 'io.evitadb:evita_external_api_grpc:2024.10.0'
<dependency>
<groupId>io.evitadb</groupId>
<artifactId>evita_external_api_graphql</artifactId>
<version>2024.10.0</version>
<version>2025.1.0</version>
<type>pom</type>
</dependency>
```
Expand All @@ -148,7 +148,7 @@ implementation 'io.evitadb:evita_external_api_graphql:2024.10.0'
<dependency>
<groupId>io.evitadb</groupId>
<artifactId>evita_external_api_rest</artifactId>
<version>2024.10.0</version>
<version>2025.1.0</version>
<type>pom</type>
</dependency>
```
Expand Down
13 changes: 13 additions & 0 deletions documentation/user/en/menu.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,19 @@
"title": "Basics",
"path": "/query/basics.md"
},
{
"title": "Header",
"children": [
{
"title": "Collection",
"path": "/query/header/collection.md"
},
{
"title": "Label",
"path": "/query/header/label.md"
}
]
},
{
"title": "Filtering",
"children": [
Expand Down
30 changes: 30 additions & 0 deletions documentation/user/en/operate/observe.md
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,36 @@ in [Logback](https://logback.qos.ch/index.html) this can be done using `%X{trace
</encoder>
```

## Traffic recording

In addition to the observability tools mentioned above, evitaDB also offers the ability to record all incoming traffic
to the server. This feature is useful for debugging and development purposes, as it allows you to play back the recorded
traffic and analyse the behaviour of the server in detail. The traffic recording feature is disabled by default and must
be enabled in the server [configuration](../operate/configure.md#traffic-recording-configuration).

These settings are recommended for local development:

```yaml
trafficRecording:
enabled: true
sourceQueryTracking: true
trafficFlushIntervalInMilliseconds: 0
```

For test/staging environments, omit `trafficFlushIntervalInMilliseconds` and leave it at the default. If you enable
traffic logging in production, disable `sourceQueryTracking` as you won't normally need to access the query source code
in production. In production you'll probably want to set a sampling rate using `trafficSamplingPercentage`.

Besides having access to the `Active Traffic Recording` tab in evitaLab, where you can list through all sessions,
queries, mutations and entity fetches, you can also issue a traffic reporting task that will save the traffic data in
a ZIP file and make it available for download. This file can be used for further analysis or to replay the traffic on
different evitaDB instances.

The recorded traffic can be browsed and filtered in evitaLab and any query can be easily executed in the corresponding
query console on the current dataset. Records can also be filtered by custom [labels](../query/header/header.md#label),
traceIds or protocol types. You can easily isolate sets of traffic records that relate to a single business case, such
as a single page rendering or a single API call.

## Reference documentation

<MDInclude>[Java Flight Recorder events](/documentation/user/en/operate/reference/jfr-events.md)</MDInclude>
Expand Down
8 changes: 4 additions & 4 deletions documentation/user/en/query/basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,14 @@ The grammar of a query is as follows:
The grammar of a full query is as follows:
</LS>

<SourceCodeTabs langSpecificTabOnly>
<SourceCodeTabs requires="evita_functional_tests/src/test/resources/META-INF/documentation/evitaql-init.java" langSpecificTabOnly>

[Example of grammar of a query](/documentation/user/en/query/examples/grammar.evitaql)
</SourceCodeTabs>

Or more complex one:

<SourceCodeTabs langSpecificTabOnly>
<SourceCodeTabs requires="evita_functional_tests/src/test/resources/META-INF/documentation/evitaql-init.java" langSpecificTabOnly>

[Example of grammar of a complex query](/documentation/user/en/query/examples/complexGrammar.evitaql)
</SourceCodeTabs>
Expand Down Expand Up @@ -134,15 +134,15 @@ I.e. the following query is still a valid query and represents the simplest quer

</LS>

<SourceCodeTabs langSpecificTabOnly>
<SourceCodeTabs requires="evita_functional_tests/src/test/resources/META-INF/documentation/evitaql-init.java" langSpecificTabOnly>

[Example of the simplest query](/documentation/user/en/query/examples/simplestQuery.evitaql)
</SourceCodeTabs>

... or even this one (although it is recommended to keep the order for better readability:
`head`, `filterBy`, `orderBy`, `require`):

<SourceCodeTabs langSpecificTabOnly>
<SourceCodeTabs requires="evita_functional_tests/src/test/resources/META-INF/documentation/evitaql-init.java" langSpecificTabOnly>

[Example random order of query parts](/documentation/user/en/query/examples/randomOrderQuery.evitaql)
</SourceCodeTabs>
Expand Down
69 changes: 50 additions & 19 deletions documentation/user/en/query/examples/complexGrammar.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,50 @@
query(
collection("Product"),
filterBy(
and(
entityPrimaryKeyInSet(1, 2, 3),
attributeEquals("visibility", "VISIBLE")
)
),
orderBy(
attributeNatural("code", ASC),
attributeNatural("priority", DESC)
),
require(
entityFetch(
attributeContentAll(), priceContentAll()
),
facetSummary()
)
)
/*
*
* _ _ ____ ____
* _____ _(_) |_ __ _| _ \| __ )
* / _ \ \ / / | __/ _` | | | | _ \
* | __/\ V /| | || (_| | |_| | |_) |
* \___| \_/ |_|\__\__,_|____/|____/
*
* Copyright (c) 2025
*
* Licensed under the Business Source License, Version 1.1 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://github.com/FgForrest/evitaDB/blob/master/LICENSE
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

final EvitaResponse<SealedEntity> entities = evita.queryCatalog(
"evita",
session -> {
return session.querySealedEntity(
query(
collection("Product"),
filterBy(
and(
entityPrimaryKeyInSet(1, 2, 3),
attributeEquals("status", "ACTIVE")
)
),
orderBy(
attributeNatural("code", ASC),
attributeNatural("catalogNumber", DESC)
),
require(
entityFetch(
attributeContentAll(),
priceContentAll()
),
facetSummary(COUNTS)
)
)
);
}
);
Loading

0 comments on commit dfed823

Please sign in to comment.