CtrlK
CommunityDocumentationLog inGet started
Tessl Logo

tessl/maven-org-springframework-ai--spring-ai-autoconfigure-vector-store-observation

Spring Boot auto-configuration module providing observability capabilities for Spring AI vector store operations through Micrometer integration. Automatically configures observation handlers for monitoring, tracing, and logging vector store queries and responses.

Overview
Eval results
Files

Spring AI Vector Store Observation Auto-Configuration

Spring Boot auto-configuration module that automatically sets up observability for Spring AI vector store operations. When this module is on the classpath along with Spring AI's vector store support, it automatically registers observation handlers for monitoring, tracing, and optional logging of vector store operations through Micrometer.

Package Information

  • Package Name: spring-ai-autoconfigure-vector-store-observation
  • Group ID: org.springframework.ai
  • Artifact ID: spring-ai-autoconfigure-vector-store-observation
  • Package Type: Maven
  • Version: 1.1.2
  • Language: Java
  • Minimum Java Version: Java 17
  • Spring Boot Version: 3.x+ (requires Spring Boot 3.0.0 or higher)
  • Installation:
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-autoconfigure-vector-store-observation</artifactId>
        <version>1.1.2</version>
    </dependency>

Core Imports

This module provides auto-configuration classes:

import org.springframework.ai.vectorstore.observation.autoconfigure.VectorStoreObservationAutoConfiguration;
import org.springframework.ai.vectorstore.observation.autoconfigure.VectorStoreObservationProperties;

The module depends on observation types from spring-ai-vector-store and spring-ai-commons, which are automatically available when those dependencies are present.

Basic Usage

This auto-configuration activates automatically when both spring-ai-vector-store and Spring Boot's observation infrastructure are on the classpath. No code changes are required for basic observability.

Automatic Activation

Simply include the dependency and ensure Spring Boot Actuator is present:

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-autoconfigure-vector-store-observation</artifactId>
    <version>1.1.2</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

The auto-configuration runs after ObservationAutoConfiguration and instruments vector store operations for metrics and tracing.

Enable Query Response Logging

To log vector store query responses (disabled by default):

spring.ai.vectorstore.observations.log-query-response=true

Security Warning: Enabling query response logging may expose sensitive or private information in logs. Use with caution. The observation handler logs this warning message on startup when enabled:

You have enabled logging out of the query response content with the risk of exposing sensitive or private information. Please, be careful!

Tracing Integration

When io.micrometer:micrometer-tracing is on the classpath, the auto-configuration registers a tracing-aware observation handler instead of the standard handler, enabling distributed tracing for vector store operations.

Complete Tracing Setup Example:

<!-- Required: Base auto-configuration -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-autoconfigure-vector-store-observation</artifactId>
    <version>1.1.2</version>
</dependency>

<!-- Required: Actuator for observation infrastructure -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<!-- Required for tracing: Micrometer Tracing -->
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-tracing</artifactId>
</dependency>

<!-- Optional: Tracing bridge (e.g., Brave for Zipkin) -->
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>

<!-- Optional: Tracing reporter (e.g., Zipkin) -->
<dependency>
    <groupId>io.zipkin.reporter2</groupId>
    <artifactId>zipkin-reporter-brave</artifactId>
</dependency>

Configuration for Tracing:

spring:
  ai:
    vectorstore:
      observations:
        log-query-response: true  # Enable observation handler
management:
  tracing:
    sampling:
      probability: 1.0  # Sample all traces (adjust for production)
  zipkin:
    tracing:
      endpoint: http://localhost:9411/api/v2/spans  # Zipkin endpoint

Architecture

This module uses Spring Boot's conditional auto-configuration to register observation handlers based on the runtime environment.

Auto-Configuration Strategy

VectorStoreObservationAutoConfiguration provides two mutually exclusive configurations:

TracerPresentObservationConfiguration: Activates when io.micrometer.tracing.Tracer is available (class and bean present). Registers a TracingAwareLoggingObservationHandler wrapping a VectorStoreQueryResponseObservationHandler to enable tracing-aware logging.

TracerNotPresentObservationConfiguration: Activates when io.micrometer.tracing.Tracer is NOT on the classpath. Registers a standard VectorStoreQueryResponseObservationHandler for basic logging.

Both configurations activate only when spring.ai.vectorstore.observations.log-query-response=true is set, allowing applications to control whether query responses are logged.

Conditional Activation

The auto-configuration uses these Spring Boot conditional annotations:

  • @ConditionalOnClass(VectorStore.class) - Requires vector store support from spring-ai-vector-store
  • @ConditionalOnClass(Tracer.class) - Requires Micrometer tracing on classpath (for tracing variant)
  • @ConditionalOnMissingClass("io.micrometer.tracing.Tracer") - Ensures tracing is NOT present (for non-tracing variant)
  • @ConditionalOnBean(Tracer.class) - Ensures Tracer bean exists in context (when class present)
  • @ConditionalOnProperty - Enables handler based on configuration property
  • @ConditionalOnMissingBean - Allows custom handler overrides

The auto-configuration runs after ObservationAutoConfiguration (via @AutoConfiguration(afterName="org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration")), ensuring the observation infrastructure is ready before registering handlers.

Bean Registration Order and Lifecycle

  1. Spring Boot Startup: Application context initialization begins
  2. ObservationAutoConfiguration: Runs first, sets up Micrometer observation infrastructure
  3. VectorStoreObservationAutoConfiguration: Runs after, evaluates conditional annotations
  4. Conditional Evaluation: Checks classpath, beans, and properties to determine which configuration to activate
  5. Bean Registration: Registers appropriate observation handler bean(s)
  6. Handler Integration: Observation handlers are automatically registered with Micrometer's ObservationRegistry
  7. Runtime: Vector store operations trigger observations, which are processed by registered handlers

Capabilities

Auto-Configuration Class

The main auto-configuration class that sets up vector store observation handlers.

package org.springframework.ai.vectorstore.observation.autoconfigure;

import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

/**
 * Auto-configuration for Spring AI vector store observation support.
 * 
 * <p>This configuration automatically registers observation handlers for monitoring
 * and logging vector store operations when the appropriate dependencies and
 * configuration properties are present.
 * 
 * <p>Activation requires:
 * <ul>
 *   <li>{@code VectorStore.class} on classpath (from spring-ai-vector-store)</li>
 *   <li>Runs after {@link ObservationAutoConfiguration} to ensure observation
 *       infrastructure is initialized</li>
 * </ul>
 * 
 * <p>This class contains two mutually exclusive nested configurations:
 * <ul>
 *   <li>{@code TracerPresentObservationConfiguration} - Registers tracing-aware handler
 *       when Micrometer tracing is available</li>
 *   <li>{@code TracerNotPresentObservationConfiguration} - Registers standard handler
 *       when tracing is not available</li>
 * </ul>
 * 
 * @see VectorStoreObservationProperties
 * @see ObservationAutoConfiguration
 */
@AutoConfiguration(afterName = "org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration")
@ConditionalOnClass(VectorStore.class)
@EnableConfigurationProperties(VectorStoreObservationProperties.class)
public class VectorStoreObservationAutoConfiguration {
    // Contains nested configuration classes that register observation handlers
}

Activation Conditions:

  • VectorStore.class must be on the classpath (from spring-ai-vector-store)
  • Activates after Spring Boot's ObservationAutoConfiguration
  • Automatically enables configuration property binding via VectorStoreObservationProperties

Nested Configuration Classes (package-private static inner classes):

  • TracerPresentObservationConfiguration - Registers tracing-aware handler when Tracer available
  • TracerNotPresentObservationConfiguration - Registers standard handler when Tracer not available

Bean Scope: Configuration class beans are singletons by default; proxyBeanMethods = false on nested classes means Spring won't create CGLIB proxies, improving startup performance.

Configuration Properties Class

Configuration properties for customizing observation behavior.

package org.springframework.ai.vectorstore.observation.autoconfigure;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * Configuration properties for vector store observations.
 * 
 * <p>These properties control the behavior of observation handlers registered by
 * {@link VectorStoreObservationAutoConfiguration}.
 * 
 * <p>Property prefix: {@value #CONFIG_PREFIX}
 * 
 * @see VectorStoreObservationAutoConfiguration
 */
@ConfigurationProperties(CONFIG_PREFIX)
public class VectorStoreObservationProperties {

    /**
     * Configuration property prefix for vector store observations.
     * Value: "spring.ai.vectorstore.observations"
     */
    public static final String CONFIG_PREFIX = "spring.ai.vectorstore.observations";

    /**
     * Whether to log the search response content in the observations.
     * 
     * <p>When enabled, observation handlers will log the full content of vector
     * store query responses, which may include:
     * <ul>
     *   <li>Retrieved document content</li>
     *   <li>Similarity scores</li>
     *   <li>Metadata associated with results</li>
     *   <li>Embedding vectors (if included in response)</li>
     * </ul>
     * 
     * <p>Default: {@code false}
     * 
     * <p><strong>Security Warning:</strong> Enabling this may expose sensitive or
     * private information in application logs. Only enable in development or when
     * you have verified that response content does not contain sensitive data.
     * Ensure proper log access controls and retention policies are in place.
     * 
     * <p>When this property is {@code true}, triggers registration of observation
     * handler beans that log query responses.
     */
    private boolean logQueryResponse = false;

    /**
     * Returns whether query response logging is enabled.
     * 
     * @return {@code true} if query response logging is enabled, {@code false} otherwise
     */
    public boolean isLogQueryResponse() {
        return this.logQueryResponse;
    }

    /**
     * Sets whether query response logging is enabled.
     * 
     * @param logQueryResponse {@code true} to enable logging, {@code false} to disable
     */
    public void setLogQueryResponse(boolean logQueryResponse) {
        this.logQueryResponse = logQueryResponse;
    }
}

Property:

  • spring.ai.vectorstore.observations.log-query-response (boolean, default: false)
    • Controls whether observation handlers log query response content
    • When enabled, triggers registration of observation handler beans
    • Warning: May expose sensitive data in logs including document content, metadata, and similarity scores
    • The property must be explicitly set to "true" (string) in properties files, or true (boolean) in YAML

Property Binding: This class is automatically bound by Spring Boot's @EnableConfigurationProperties annotation on VectorStoreObservationAutoConfiguration.

Bean Registration (Without Tracing)

When Micrometer tracing is NOT available, registers a standard observation handler.

package org.springframework.ai.vectorstore.observation.autoconfigure;

import org.springframework.ai.vectorstore.observation.VectorStoreQueryResponseObservationHandler;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Configuration for vector store observation when Micrometer tracing is not available.
 * 
 * <p>This configuration registers a standard {@link VectorStoreQueryResponseObservationHandler}
 * that logs query responses without tracing integration.
 * 
 * <p>Activation requires:
 * <ul>
 *   <li>{@code io.micrometer.tracing.Tracer} class NOT on classpath</li>
 *   <li>{@code spring.ai.vectorstore.observations.log-query-response=true}</li>
 *   <li>No existing {@link VectorStoreQueryResponseObservationHandler} bean</li>
 * </ul>
 */
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingClass("io.micrometer.tracing.Tracer")
static class TracerNotPresentObservationConfiguration {

    /**
     * Registers a VectorStoreQueryResponseObservationHandler when tracing is not available.
     * 
     * <p>This handler logs vector store query responses to help with debugging and
     * monitoring. It logs a warning message on startup about potential sensitive data
     * exposure.
     * 
     * <p>Bean name: {@code vectorStoreQueryResponseObservationHandler}
     * <p>Bean scope: Singleton (default)
     * <p>Lazy initialization: No (eager by default)
     * 
     * @return a new instance of VectorStoreQueryResponseObservationHandler
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = VectorStoreObservationProperties.CONFIG_PREFIX,
        name = "log-query-response",
        havingValue = "true"
    )
    public VectorStoreQueryResponseObservationHandler vectorStoreQueryResponseObservationHandler() {
        return new VectorStoreQueryResponseObservationHandler();
    }
}

Bean: vectorStoreQueryResponseObservationHandler

  • Type: VectorStoreQueryResponseObservationHandler (from spring-ai-vector-store)
  • Bean Name: "vectorStoreQueryResponseObservationHandler"
  • Scope: Singleton (default for @Bean methods)
  • Lazy: No (initialized eagerly at startup)
  • Conditions:
    • io.micrometer.tracing.Tracer class NOT on classpath
    • spring.ai.vectorstore.observations.log-query-response=true (exact value match)
    • No existing VectorStoreQueryResponseObservationHandler bean in context
  • Behavior:
    • Creates a new instance of VectorStoreQueryResponseObservationHandler
    • Logs a warning on startup: "You have enabled logging out of the query response content with the risk of exposing sensitive or private information. Please, be careful!"
    • Automatically registered with Micrometer's ObservationRegistry
    • Processes observations with context type VectorStoreObservationContext

Handler Lifecycle:

  1. Bean created during application startup
  2. Constructor logs security warning
  3. Automatically registered with ObservationRegistry by Spring Boot
  4. Invoked for each vector store observation event
  5. Logs query response content to application logs

Bean Registration (With Tracing)

When Micrometer tracing IS available, registers a tracing-aware observation handler.

package org.springframework.ai.vectorstore.observation.autoconfigure;

import io.micrometer.tracing.Tracer;
import org.springframework.ai.observation.tracing.TracingAwareLoggingObservationHandler;
import org.springframework.ai.vectorstore.observation.VectorStoreObservationContext;
import org.springframework.ai.vectorstore.observation.VectorStoreQueryResponseObservationHandler;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Configuration for vector store observation when Micrometer tracing is available.
 * 
 * <p>This configuration registers a {@link TracingAwareLoggingObservationHandler} that
 * wraps {@link VectorStoreQueryResponseObservationHandler} to provide tracing-aware
 * logging with proper log correlation.
 * 
 * <p>Activation requires:
 * <ul>
 *   <li>{@code io.micrometer.tracing.Tracer} class on classpath</li>
 *   <li>{@code Tracer} bean exists in application context</li>
 *   <li>{@code spring.ai.vectorstore.observations.log-query-response=true}</li>
 *   <li>No existing {@link VectorStoreQueryResponseObservationHandler} bean</li>
 * </ul>
 * 
 * <p>The tracing-aware handler adds trace and span IDs to log messages, enabling
 * correlation between logs and distributed traces in observability platforms.
 */
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Tracer.class)
@ConditionalOnBean(Tracer.class)
static class TracerPresentObservationConfiguration {

    /**
     * Registers a tracing-aware observation handler when Micrometer tracing is available.
     * 
     * <p>This handler wraps a {@link VectorStoreQueryResponseObservationHandler} with
     * {@link TracingAwareLoggingObservationHandler} to add trace context (trace ID,
     * span ID) to log messages.
     * 
     * <p>The handler logs query responses with full tracing context, allowing logs to
     * be correlated with distributed traces in systems like Zipkin, Jaeger, or
     * Application Insights.
     * 
     * <p>Bean name: {@code vectorStoreQueryResponseObservationHandler}
     * <p>Bean scope: Singleton (default)
     * <p>Lazy initialization: No (eager by default)
     * 
     * @param tracer the Micrometer Tracer bean for distributed tracing integration;
     *               injected by Spring when available in the context
     * @return a new instance of TracingAwareLoggingObservationHandler wrapping
     *         VectorStoreQueryResponseObservationHandler
     */
    @Bean
    @ConditionalOnMissingBean(
        value = VectorStoreQueryResponseObservationHandler.class,
        name = "vectorStoreQueryResponseObservationHandler"
    )
    @ConditionalOnProperty(
        prefix = VectorStoreObservationProperties.CONFIG_PREFIX,
        name = "log-query-response",
        havingValue = "true"
    )
    public TracingAwareLoggingObservationHandler<VectorStoreObservationContext> vectorStoreQueryResponseObservationHandler(
            Tracer tracer) {
        return new TracingAwareLoggingObservationHandler<>(
            new VectorStoreQueryResponseObservationHandler(), 
            tracer
        );
    }
}

Bean: vectorStoreQueryResponseObservationHandler

  • Type: TracingAwareLoggingObservationHandler<VectorStoreObservationContext> (from spring-ai-commons)
  • Bean Name: "vectorStoreQueryResponseObservationHandler"
  • Scope: Singleton (default for @Bean methods)
  • Lazy: No (initialized eagerly at startup)
  • Parameters:
    • tracer (Tracer) - Micrometer Tracer for distributed tracing, injected by Spring
  • Conditions:
    • io.micrometer.tracing.Tracer class on classpath
    • Tracer bean exists in application context
    • spring.ai.vectorstore.observations.log-query-response=true (exact value match)
    • No existing VectorStoreQueryResponseObservationHandler bean or bean named vectorStoreQueryResponseObservationHandler
  • Behavior:
    • Wraps VectorStoreQueryResponseObservationHandler with tracing awareness
    • Constructor of wrapped handler logs security warning
    • Adds trace ID and span ID to log messages
    • Automatically registered with Micrometer's ObservationRegistry
    • Processes observations with context type VectorStoreObservationContext

Handler Structure:

TracingAwareLoggingObservationHandler
  └── wraps: VectorStoreQueryResponseObservationHandler
      └── logs: query response content with trace context

Trace Context in Logs: When active, log messages include structured trace information such as:

[traceId=64c3a3c3e8b3a9d1 spanId=64c3a3c3e8b3a9d1] Vector store query response: [content...]

Registered Observation Handlers

The auto-configuration registers observation handler beans that integrate with Spring AI's vector store observation infrastructure. These handlers are from the spring-ai-vector-store and spring-ai-commons modules.

Handler Behavior

When spring.ai.vectorstore.observations.log-query-response=true is set:

  1. Without Tracing: Registers VectorStoreQueryResponseObservationHandler which logs query response content to the application logger
  2. With Tracing: Registers TracingAwareLoggingObservationHandler wrapping the query response handler, enabling log correlation with distributed traces by adding trace and span IDs

Both variants log this warning on startup:

You have enabled logging out of the query response content with the risk of exposing sensitive or private information. Please, be careful!

Handler Method Signatures

The observation handlers implement Micrometer's ObservationHandler interface for processing observation events.

VectorStoreQueryResponseObservationHandler (from spring-ai-vector-store):

package org.springframework.ai.vectorstore.observation;

import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationHandler;

/**
 * Handler that logs vector store query responses.
 * 
 * <p>Supports observations with context type {@link VectorStoreObservationContext}.
 */
public class VectorStoreQueryResponseObservationHandler 
        implements ObservationHandler<VectorStoreObservationContext> {
    
    /**
     * Constructor that logs a security warning about sensitive data exposure.
     */
    public VectorStoreQueryResponseObservationHandler();
    
    /**
     * Indicates this handler supports VectorStoreObservationContext.
     * 
     * @param context the observation context to check
     * @return true if context is an instance of VectorStoreObservationContext
     */
    @Override
    public boolean supportsContext(Observation.Context context);
    
    /**
     * Called when an observation stops. Logs the query response content.
     * 
     * @param context the observation context containing query and response data
     */
    @Override
    public void onStop(VectorStoreObservationContext context);
}

TracingAwareLoggingObservationHandler (from spring-ai-commons):

package org.springframework.ai.observation.tracing;

import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationHandler;
import io.micrometer.tracing.Tracer;

/**
 * Generic tracing-aware wrapper for observation handlers that adds trace context to logs.
 * 
 * @param <T> the observation context type
 */
public class TracingAwareLoggingObservationHandler<T extends Observation.Context> 
        implements ObservationHandler<T> {
    
    /**
     * Creates a tracing-aware handler wrapping a delegate.
     * 
     * @param delegate the handler to wrap
     * @param tracer the tracer for accessing current trace context
     */
    public TracingAwareLoggingObservationHandler(ObservationHandler<T> delegate, Tracer tracer);
    
    /**
     * Delegates to wrapped handler's supportsContext method.
     * 
     * @param context the observation context to check
     * @return true if the delegate supports the context
     */
    @Override
    public boolean supportsContext(Observation.Context context);
    
    /**
     * Called when observation stops. Extracts trace context and delegates to wrapped handler.
     * 
     * @param context the observation context
     */
    @Override
    public void onStop(T context);
    
    /**
     * Additional handler lifecycle methods (onStart, onError, etc.) delegate to wrapped handler.
     */
}

Integration with Vector Store Observations

The registered handlers work with:

  • VectorStoreObservationContext - Captures operation metadata including query, filter, topK, similarity threshold, and response (from spring-ai-vector-store)
  • VectorStoreObservationConvention - Defines observation naming and tagging conventions (from spring-ai-vector-store)
  • DefaultVectorStoreObservationConvention - Default implementation of naming conventions (from spring-ai-vector-store)
  • Micrometer's observation infrastructure - Exports metrics and traces to configured backends

Observation Event Flow:

Vector Store Operation
    ↓
Observation.createNotStarted()
    ↓
Observation.start()
    ↓
VectorStore.similaritySearch() / add() / delete()
    ↓
Observation.stop()
    ↓
ObservationHandler.onStop()
    ↓
VectorStoreQueryResponseObservationHandler logs response
    ↓
Metrics exported to backend (Prometheus, etc.)
Traces exported to backend (Zipkin, Jaeger, etc.)

For details on the observation context, conventions, and metadata keys, refer to the spring-ai-vector-store module documentation.

Observation Metadata and Keys

The observation handlers process contexts containing these key metadata elements:

Query Metadata (captured in VectorStoreObservationContext):

  • Query text or embedding vector
  • Search filter criteria
  • Top K results requested
  • Similarity threshold
  • Vector store operation type (query, add, delete)

Response Metadata (logged when enabled):

  • Retrieved documents and their content
  • Similarity scores for each result
  • Document metadata
  • Total results count

Standard Observation Tags (added by convention):

  • db.system - Vector store type (e.g., "pinecone", "redis", "chromadb")
  • db.operation - Operation type (e.g., "query", "add", "delete")
  • db.vector_query.top_k - Number of results requested
  • db.vector_query.similarity_threshold - Minimum similarity score
  • Additional tags defined by VectorStoreObservationConvention

Dependency Types Reference

This auto-configuration module uses types from other Spring AI modules. These are provided for reference but are not part of this package's API.

From spring-ai-vector-store

The following types are used by this auto-configuration:

  • VectorStoreObservationContext - Context object for vector store observations; extends Observation.Context
  • VectorStoreQueryResponseObservationHandler - Handler that logs query responses
  • VectorStoreObservationConvention - Interface for observation naming conventions
  • DefaultVectorStoreObservationConvention - Default convention implementation
  • VectorStoreObservationDocumentation - Observation key name documentation and metadata
  • VectorStore - Interface used in conditional checks; base interface for all vector store implementations

VectorStoreObservationContext Key Methods:

package org.springframework.ai.vectorstore.observation;

import io.micrometer.observation.Observation;
import java.util.List;

/**
 * Observation context for vector store operations.
 */
public class VectorStoreObservationContext extends Observation.Context {
    
    /**
     * Gets the query text or description.
     * @return the query string
     */
    public String getQuery();
    
    /**
     * Sets the query text.
     * @param query the query to set
     */
    public void setQuery(String query);
    
    /**
     * Gets the search filter expression.
     * @return the filter criteria
     */
    public String getFilter();
    
    /**
     * Sets the search filter.
     * @param filter the filter to apply
     */
    public void setFilter(String filter);
    
    /**
     * Gets the number of top results requested.
     * @return the topK value
     */
    public Integer getTopK();
    
    /**
     * Sets the number of top results to retrieve.
     * @param topK the maximum number of results
     */
    public void setTopK(Integer topK);
    
    /**
     * Gets the similarity threshold for filtering results.
     * @return the threshold value (typically 0.0 to 1.0)
     */
    public Double getSimilarityThreshold();
    
    /**
     * Sets the similarity threshold.
     * @param threshold the minimum similarity score
     */
    public void setSimilarityThreshold(Double threshold);
    
    /**
     * Gets the query response/results.
     * @return list of search results
     */
    public List<?> getQueryResponse();
    
    /**
     * Sets the query response.
     * @param response the search results
     */
    public void setQueryResponse(List<?> response);
    
    /**
     * Gets the operation type.
     * @return operation name (e.g., "query", "add", "delete")
     */
    public String getOperationType();
    
    /**
     * Sets the operation type.
     * @param operationType the operation name
     */
    public void setOperationType(String operationType);
}

For complete API documentation of these types, refer to the spring-ai-vector-store module.

From spring-ai-commons

  • TracingAwareLoggingObservationHandler<T> - Wraps observation handlers to provide tracing-aware logging with trace and span ID correlation

TracingAwareLoggingObservationHandler Constructor:

package org.springframework.ai.observation.tracing;

import io.micrometer.observation.ObservationHandler;
import io.micrometer.tracing.Tracer;

/**
 * Constructs a tracing-aware wrapper.
 * 
 * @param delegate the handler to wrap; must not be null
 * @param tracer the tracer for trace context; must not be null
 * @throws IllegalArgumentException if delegate or tracer is null
 */
public TracingAwareLoggingObservationHandler(
    ObservationHandler<T> delegate, 
    Tracer tracer
);

For complete API documentation, refer to the spring-ai-commons module.

Configuration Reference

Property: log-query-response

Controls whether observation handlers are registered to log vector store query responses.

Properties format:

spring.ai.vectorstore.observations.log-query-response=true

YAML format:

spring:
  ai:
    vectorstore:
      observations:
        log-query-response: true

Environment Variable format:

export SPRING_AI_VECTORSTORE_OBSERVATIONS_LOG_QUERY_RESPONSE=true

Command-Line Argument format:

java -jar app.jar --spring.ai.vectorstore.observations.log-query-response=true
  • Type: boolean
  • Default: false
  • Effect: When true, registers observation handler beans that log query response content
  • Warning: May expose sensitive information in logs including:
    • Document content (full text or excerpts)
    • User queries
    • Similarity scores
    • Document metadata (authors, timestamps, categories, etc.)
    • Embedding vectors (if included in response objects)
  • String Value Matching: The @ConditionalOnProperty annotation uses havingValue="true", so the property must be set to the exact string "true" (case-insensitive) in properties files

Property Precedence (Spring Boot standard order):

  1. Command-line arguments (--spring.ai.vectorstore.observations.log-query-response=true)
  2. SPRING_APPLICATION_JSON properties
  3. ServletConfig init parameters
  4. ServletContext init parameters
  5. JNDI attributes from java:comp/env
  6. Java System properties (System.getProperties())
  7. OS environment variables (SPRING_AI_VECTORSTORE_OBSERVATIONS_LOG_QUERY_RESPONSE)
  8. RandomValuePropertySource
  9. Profile-specific application properties (application-{profile}.properties)
  10. Application properties (application.properties or application.yml)

Integration with Spring Boot

This auto-configuration integrates with Spring Boot's observability infrastructure:

  1. Automatic Activation: When spring-ai-vector-store is on the classpath, auto-configuration activates automatically via Spring Boot's auto-configuration mechanism
  2. Observation Infrastructure: Runs after ObservationAutoConfiguration to ensure Micrometer observation support is ready
  3. Conditional Registration: Uses @ConditionalOnClass, @ConditionalOnBean, @ConditionalOnMissingBean, @ConditionalOnProperty, and @ConditionalOnMissingClass to register the appropriate handler variant
  4. Property Binding: Automatically binds spring.ai.vectorstore.observations.* properties via VectorStoreObservationProperties
  5. Metrics Export: Observations are automatically exported as metrics to configured Micrometer registries (Prometheus, Atlas, Datadog, etc.)
  6. Tracing Export: When tracing is enabled, observations include trace and span information exported to tracing backends (Zipkin, Jaeger, etc.)

Auto-Configuration Discovery

This module includes a META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports file that lists:

org.springframework.ai.vectorstore.observation.autoconfigure.VectorStoreObservationAutoConfiguration

Spring Boot's auto-configuration mechanism automatically discovers and processes this class during application startup.

Overriding Default Handlers

Custom observation handlers can be registered by defining beans that satisfy the @ConditionalOnMissingBean conditions:

Option 1: Override with Same Bean Name

import org.springframework.ai.vectorstore.observation.VectorStoreQueryResponseObservationHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CustomObservationConfig {

    @Bean
    public VectorStoreQueryResponseObservationHandler vectorStoreQueryResponseObservationHandler() {
        // Custom handler implementation or subclass
        return new CustomVectorStoreQueryResponseObservationHandler();
    }
}

Option 2: Override with Custom Implementation

import org.springframework.ai.vectorstore.observation.VectorStoreObservationContext;
import io.micrometer.observation.ObservationHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CustomObservationConfig {

    @Bean
    public ObservationHandler<VectorStoreObservationContext> customVectorStoreHandler() {
        return new ObservationHandler<VectorStoreObservationContext>() {
            @Override
            public boolean supportsContext(Observation.Context context) {
                return context instanceof VectorStoreObservationContext;
            }
            
            @Override
            public void onStop(VectorStoreObservationContext context) {
                // Custom logging, metrics, or processing logic
                // Can filter sensitive data before logging
                String sanitizedResponse = sanitize(context.getQueryResponse());
                log.info("Vector store response: {}", sanitizedResponse);
            }
            
            private String sanitize(List<?> response) {
                // Remove or redact sensitive information
                return "Returned " + response.size() + " results";
            }
        };
    }
}

Option 3: Additional Handler (does not override)

import org.springframework.ai.vectorstore.observation.VectorStoreObservationContext;
import io.micrometer.observation.ObservationHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AdditionalObservationConfig {

    /**
     * Registers an additional handler that runs alongside the default handler.
     * Both handlers will process observations.
     */
    @Bean
    public ObservationHandler<VectorStoreObservationContext> metricsOnlyHandler() {
        return new ObservationHandler<VectorStoreObservationContext>() {
            @Override
            public boolean supportsContext(Observation.Context context) {
                return context instanceof VectorStoreObservationContext;
            }
            
            @Override
            public void onStop(VectorStoreObservationContext context) {
                // Export custom metrics without logging sensitive data
                int resultCount = context.getQueryResponse() != null 
                    ? context.getQueryResponse().size() 
                    : 0;
                // Record metric...
            }
        };
    }
}

The auto-configuration's @ConditionalOnMissingBean ensures custom beans take precedence when the bean name or type matches.

Disabling Auto-Configuration

To completely disable vector store observation auto-configuration:

application.properties:

spring.autoconfigure.exclude=org.springframework.ai.vectorstore.observation.autoconfigure.VectorStoreObservationAutoConfiguration

application.yml:

spring:
  autoconfigure:
    exclude:
      - org.springframework.ai.vectorstore.observation.autoconfigure.VectorStoreObservationAutoConfiguration

@SpringBootApplication annotation:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.ai.vectorstore.observation.autoconfigure.VectorStoreObservationAutoConfiguration;

@SpringBootApplication(exclude = VectorStoreObservationAutoConfiguration.class)
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Dependencies

Required

  • org.springframework.ai:spring-ai-vector-store - Provides observation infrastructure, types, and handlers
    • Minimum version: Aligned with spring-ai-autoconfigure-vector-store-observation version
    • Provides: VectorStore, VectorStoreObservationContext, VectorStoreQueryResponseObservationHandler
  • org.springframework.boot:spring-boot-starter - Spring Boot core and auto-configuration support
    • Minimum version: 3.0.0
    • Provides: @AutoConfiguration, @EnableConfigurationProperties, conditional annotations

Optional

  • io.micrometer:micrometer-tracing - Enables tracing-aware handler variant
    • When present: Registers TracingAwareLoggingObservationHandler with trace context
    • When absent: Registers standard VectorStoreQueryResponseObservationHandler
    • Provides: Tracer interface for trace context access
  • org.springframework.boot:spring-boot-starter-actuator - Provides observation infrastructure via ObservationAutoConfiguration
    • Recommended for production use
    • Provides: ObservationRegistry, ObservationAutoConfiguration
    • Without this, observations may not be processed or exported

Build-Time Only

  • org.springframework.boot:spring-boot-configuration-processor - Generates configuration metadata for IDE support
    • Scope: optional or provided
    • Generates: META-INF/spring-configuration-metadata.json
  • org.springframework.boot:spring-boot-autoconfigure-processor - Generates auto-configuration metadata
    • Scope: optional or provided
    • Generates: META-INF/spring-autoconfigure-metadata.json

Transitive Dependencies

The following dependencies are transitively included via spring-ai-vector-store and spring-boot-starter-actuator:

  • io.micrometer:micrometer-observation - Core observation API
  • io.micrometer:micrometer-core - Metrics infrastructure
  • org.springframework:spring-context - Spring Framework core
  • org.springframework:spring-boot - Spring Boot core

Complete Maven Dependency Example

Minimal Setup (Without Tracing):

<dependencies>
    <!-- Spring AI Vector Store Observation Auto-Configuration -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-autoconfigure-vector-store-observation</artifactId>
        <version>1.1.2</version>
    </dependency>
    
    <!-- Required: Actuator for observation infrastructure -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    
    <!-- Required: Vector store implementation (example: ChromaDB) -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-chroma-store</artifactId>
    </dependency>
</dependencies>

Full Setup (With Tracing and Metrics Export):

<dependencies>
    <!-- Spring AI Vector Store Observation Auto-Configuration -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-autoconfigure-vector-store-observation</artifactId>
        <version>1.1.2</version>
    </dependency>
    
    <!-- Required: Actuator -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    
    <!-- Required: Vector store implementation -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-chroma-store</artifactId>
    </dependency>
    
    <!-- Optional: Micrometer Tracing for trace context -->
    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-tracing</artifactId>
    </dependency>
    
    <!-- Optional: Tracing bridge (Brave for Zipkin) -->
    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-tracing-bridge-brave</artifactId>
    </dependency>
    
    <!-- Optional: Zipkin reporter -->
    <dependency>
        <groupId>io.zipkin.reporter2</groupId>
        <artifactId>zipkin-reporter-brave</artifactId>
    </dependency>
    
    <!-- Optional: Prometheus metrics export -->
    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-registry-prometheus</artifactId>
    </dependency>
</dependencies>

Usage Examples

Example 1: Basic Observation with Logging

Enable query response logging for debugging:

application.yml:

spring:
  ai:
    vectorstore:
      observations:
        log-query-response: true

logging:
  level:
    org.springframework.ai.vectorstore.observation: DEBUG

Result: All vector store operations log query responses to the application logger.

Example 2: Observation with Distributed Tracing

Enable tracing to correlate vector store operations with distributed traces:

pom.xml:

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>
<dependency>
    <groupId>io.zipkin.reporter2</groupId>
    <artifactId>zipkin-reporter-brave</artifactId>
</dependency>

application.yml:

spring:
  ai:
    vectorstore:
      observations:
        log-query-response: true
management:
  tracing:
    sampling:
      probability: 1.0
  zipkin:
    tracing:
      endpoint: http://localhost:9411/api/v2/spans

Result: Vector store operations appear as spans in distributed traces with query response logs correlated via trace ID.

Example 3: Metrics Export to Prometheus

Export vector store metrics without logging sensitive responses:

pom.xml:

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

application.yml:

spring:
  ai:
    vectorstore:
      observations:
        log-query-response: false  # Disable logging

management:
  endpoints:
    web:
      exposure:
        include: prometheus
  metrics:
    export:
      prometheus:
        enabled: true

Result: Metrics like vectorstore.query.duration, vectorstore.query.count exported to Prometheus without logging response content. Access metrics at /actuator/prometheus.

Example 4: Custom Observation Handler with Filtering

Create a custom handler that filters sensitive data before logging:

import org.springframework.ai.vectorstore.observation.VectorStoreObservationContext;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.stream.Collectors;

@Configuration
public class FilteredObservationConfig {
    
    private static final Logger log = LoggerFactory.getLogger(FilteredObservationConfig.class);

    /**
     * Custom handler that logs response metadata without sensitive content.
     */
    @Bean
    public ObservationHandler<VectorStoreObservationContext> vectorStoreQueryResponseObservationHandler() {
        return new ObservationHandler<VectorStoreObservationContext>() {
            
            @Override
            public boolean supportsContext(Observation.Context context) {
                return context instanceof VectorStoreObservationContext;
            }
            
            @Override
            public void onStop(VectorStoreObservationContext context) {
                // Log metadata without sensitive content
                int resultCount = context.getQueryResponse() != null 
                    ? context.getQueryResponse().size() 
                    : 0;
                
                log.info("Vector store query completed: operation={}, topK={}, resultCount={}, similarityThreshold={}", 
                    context.getOperationType(),
                    context.getTopK(),
                    resultCount,
                    context.getSimilarityThreshold()
                );
                
                // Optionally log filtered/redacted results
                if (context.getQueryResponse() != null && !context.getQueryResponse().isEmpty()) {
                    List<String> resultSummaries = context.getQueryResponse().stream()
                        .map(result -> "Document[id=..., score=...]") // Redact actual content
                        .limit(5) // Limit to first 5
                        .collect(Collectors.toList());
                    log.debug("Sample results: {}", resultSummaries);
                }
            }
        };
    }
}

application.yml:

spring:
  ai:
    vectorstore:
      observations:
        log-query-response: true  # Enables handler registration

Result: Logs vector store metrics and metadata without exposing document content or queries.

Example 5: Conditional Handler Based on Profile

Enable detailed logging only in development:

import org.springframework.ai.vectorstore.observation.VectorStoreQueryResponseObservationHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

@Configuration
public class ProfileBasedObservationConfig {

    /**
     * In development, use default handler with full logging.
     */
    @Bean
    @Profile("dev")
    public VectorStoreQueryResponseObservationHandler devObservationHandler() {
        return new VectorStoreQueryResponseObservationHandler();
    }
    
    /**
     * In production, use custom handler with filtered logging.
     */
    @Bean
    @Profile("prod")
    public ObservationHandler<VectorStoreObservationContext> prodObservationHandler() {
        return new FilteredLoggingHandler(); // Custom implementation
    }
}

application-dev.yml:

spring:
  ai:
    vectorstore:
      observations:
        log-query-response: true
logging:
  level:
    org.springframework.ai: DEBUG

application-prod.yml:

spring:
  ai:
    vectorstore:
      observations:
        log-query-response: true
logging:
  level:
    org.springframework.ai: INFO

Result: Development environment logs full responses; production logs only metadata.

Troubleshooting

Handler Not Registered

Symptom: Vector store operations are not logged or observed.

Causes and Solutions:

  1. Property not set: Ensure spring.ai.vectorstore.observations.log-query-response=true

    spring:
      ai:
        vectorstore:
          observations:
            log-query-response: true
  2. Missing Actuator dependency: Add Spring Boot Actuator

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
  3. Missing vector store dependency: Ensure a vector store implementation is present

    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-chroma-store</artifactId>
    </dependency>
  4. Auto-configuration excluded: Check that VectorStoreObservationAutoConfiguration is not excluded

    # Remove or comment out:
    # spring:
    #   autoconfigure:
    #     exclude:
    #       - org.springframework.ai.vectorstore.observation.autoconfigure.VectorStoreObservationAutoConfiguration
  5. Custom bean overriding: Check if a custom handler bean is preventing registration

    • Use @ConditionalOnMissingBean on custom handlers if you want fallback behavior

Verification: Enable debug logging to see auto-configuration decisions:

logging:
  level:
    org.springframework.boot.autoconfigure: DEBUG

Tracing Context Not Available

Symptom: Logs don't include trace ID and span ID despite having Micrometer Tracing on classpath.

Causes and Solutions:

  1. Tracer bean not registered: Ensure a Tracer implementation is configured

    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-tracing-bridge-brave</artifactId>
    </dependency>
  2. Tracing not enabled: Configure tracing sampling

    management:
      tracing:
        sampling:
          probability: 1.0
  3. Wrong handler registered: Check which handler is active

    # Should show TracingAwareLoggingObservationHandler
    curl http://localhost:8080/actuator/beans | jq '.contexts[].beans | to_entries[] | select(.key | contains("vectorStoreQuery"))'

Performance Impact

Symptom: Application performance degrades with observation enabled.

Causes and Solutions:

  1. Excessive logging: Disable query response logging in production

    spring:
      ai:
        vectorstore:
          observations:
            log-query-response: false  # Disable in production
  2. High sampling rate: Reduce tracing sampling for high-throughput applications

    management:
      tracing:
        sampling:
          probability: 0.1  # Sample 10% of traces
  3. Large responses: Implement custom handler that logs summaries instead of full content

    @Bean
    public ObservationHandler<VectorStoreObservationContext> optimizedHandler() {
        return new SummaryOnlyObservationHandler();
    }

Sensitive Data Exposure

Symptom: Sensitive information appears in logs.

Solutions:

  1. Disable logging: Turn off query response logging

    spring:
      ai:
        vectorstore:
          observations:
            log-query-response: false
  2. Use custom handler with filtering: Implement a handler that redacts sensitive data

    @Bean
    public ObservationHandler<VectorStoreObservationContext> secureHandler() {
        return new RedactingSensitiveDataHandler();
    }
  3. Configure log masking: Use logging framework features to mask patterns

    <!-- Logback configuration -->
    <configuration>
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
                <layout class="ch.qos.logback.classic.PatternLayout">
                    <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
                </layout>
                <maskingRule>
                    <regex>email\":\s*\"([^\"]+)\"</regex>
                    <replacement>email": "***@***.***"</replacement>
                </maskingRule>
            </encoder>
        </appender>
    </configuration>

Metrics Not Exported

Symptom: Vector store metrics don't appear in Prometheus or other backends.

Causes and Solutions:

  1. Missing metrics registry: Add Micrometer registry dependency

    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-registry-prometheus</artifactId>
    </dependency>
  2. Endpoint not exposed: Expose metrics endpoint

    management:
      endpoints:
        web:
          exposure:
            include: prometheus,metrics
  3. Observation not started: Ensure vector store operations use Spring AI's observation-enabled implementations

  4. Verify metrics: Check available metrics

    curl http://localhost:8080/actuator/metrics | jq '.names[] | select(. | contains("vector"))'

ClassNotFoundException or NoClassDefFoundError

Symptom: Application fails to start with missing class errors.

Common Scenarios:

  1. Missing spring-ai-vector-store:

    java.lang.ClassNotFoundException: org.springframework.ai.vectorstore.VectorStore

    Solution: Add vector store dependency

    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-chroma-store</artifactId>
    </dependency>
  2. Missing Micrometer Observation:

    java.lang.NoClassDefFoundError: io/micrometer/observation/Observation

    Solution: Add Spring Boot Actuator (includes Micrometer)

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
  3. Tracing class missing:

    java.lang.ClassNotFoundException: io.micrometer.tracing.Tracer

    Solution: This is expected if tracing is not intended; the auto-configuration handles this via @ConditionalOnClass. If tracing is intended, add:

    <dependency>
        <groupId>io.micrometer</groupId>
        <artifactId>micrometer-tracing</artifactId>
    </dependency>

Advanced Integration Patterns

Pattern 1: Multi-Registry Metrics Export

Export vector store metrics to multiple backends simultaneously:

management:
  metrics:
    export:
      prometheus:
        enabled: true
      datadog:
        enabled: true
        api-key: ${DATADOG_API_KEY}
      cloudwatch:
        enabled: true
        namespace: VectorStoreApp

Dependencies:

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-datadog</artifactId>
</dependency>
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-cloudwatch2</artifactId>
</dependency>

Pattern 2: Custom Observation Convention

Override observation naming and tagging conventions:

import org.springframework.ai.vectorstore.observation.VectorStoreObservationConvention;
import org.springframework.ai.vectorstore.observation.VectorStoreObservationContext;
import io.micrometer.observation.Observation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CustomConventionConfig {

    @Bean
    public VectorStoreObservationConvention customVectorStoreConvention() {
        return new VectorStoreObservationConvention() {
            
            @Override
            public String getName() {
                return "custom.vectorstore.query"; // Custom observation name
            }
            
            @Override
            public String getContextualName(VectorStoreObservationContext context) {
                return "vectorstore." + context.getOperationType();
            }
            
            @Override
            public KeyValues getLowCardinalityKeyValues(VectorStoreObservationContext context) {
                return KeyValues.of(
                    "store.type", "custom",
                    "operation", context.getOperationType(),
                    "has.filter", context.getFilter() != null ? "true" : "false"
                );
            }
            
            @Override
            public KeyValues getHighCardinalityKeyValues(VectorStoreObservationContext context) {
                return KeyValues.of(
                    "query.topk", String.valueOf(context.getTopK()),
                    "query.threshold", String.valueOf(context.getSimilarityThreshold())
                );
            }
        };
    }
}

Pattern 3: Composite Observation Handler

Create a handler that performs multiple actions:

import org.springframework.ai.vectorstore.observation.VectorStoreObservationContext;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.atomic.AtomicInteger;

@Configuration
public class CompositeHandlerConfig {

    private final AtomicInteger queryCounter = new AtomicInteger(0);

    @Bean
    public ObservationHandler<VectorStoreObservationContext> compositeHandler() {
        return new ObservationHandler<VectorStoreObservationContext>() {
            
            @Override
            public boolean supportsContext(Observation.Context context) {
                return context instanceof VectorStoreObservationContext;
            }
            
            @Override
            public void onStart(VectorStoreObservationContext context) {
                // Log query initiation
                queryCounter.incrementAndGet();
            }
            
            @Override
            public void onStop(VectorStoreObservationContext context) {
                // Log results summary
                int resultCount = context.getQueryResponse() != null 
                    ? context.getQueryResponse().size() 
                    : 0;
                
                // Update custom metrics
                // recordCustomMetrics(context, resultCount);
                
                // Send to external monitoring
                // sendToExternalSystem(context);
                
                // Log sanitized summary
                log.info("Query #{}: operation={}, results={}", 
                    queryCounter.get(), 
                    context.getOperationType(), 
                    resultCount
                );
            }
            
            @Override
            public void onError(VectorStoreObservationContext context) {
                // Handle and log errors
                log.error("Query #{} failed: operation={}", 
                    queryCounter.get(), 
                    context.getOperationType()
                );
            }
        };
    }
}

Pattern 4: Conditional Observation Based on Operation Type

Only observe specific types of vector store operations:

import org.springframework.ai.vectorstore.observation.VectorStoreObservationContext;
import io.micrometer.observation.ObservationHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SelectiveObservationConfig {

    @Bean
    public ObservationHandler<VectorStoreObservationContext> selectiveHandler() {
        return new ObservationHandler<VectorStoreObservationContext>() {
            
            @Override
            public boolean supportsContext(Observation.Context context) {
                if (!(context instanceof VectorStoreObservationContext)) {
                    return false;
                }
                
                VectorStoreObservationContext vsContext = (VectorStoreObservationContext) context;
                // Only observe query operations, not add/delete
                return "query".equals(vsContext.getOperationType());
            }
            
            @Override
            public void onStop(VectorStoreObservationContext context) {
                // Process only query operations
                log.info("Query operation completed with {} results", 
                    context.getQueryResponse() != null ? context.getQueryResponse().size() : 0
                );
            }
        };
    }
}

Version Compatibility

Spring Boot Compatibility

  • Spring Boot 3.0.x: Compatible
  • Spring Boot 3.1.x: Compatible
  • Spring Boot 3.2.x: Compatible (recommended)
  • Spring Boot 3.3.x+: Compatible
  • Spring Boot 2.x: Not compatible (requires Spring Boot 3.x for auto-configuration metadata format)

Java Version Requirements

  • Minimum: Java 17
  • Recommended: Java 21
  • Maximum tested: Java 21

Spring AI Version Alignment

This module version 1.1.2 is designed to work with Spring AI 1.1.x releases. Ensure all Spring AI modules use compatible versions:

<properties>
    <spring-ai.version>1.1.2</spring-ai.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-autoconfigure-vector-store-observation</artifactId>
        <version>${spring-ai.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-chroma-store</artifactId>
        <version>${spring-ai.version}</version>
    </dependency>
</dependencies>

Micrometer Version Compatibility

  • Micrometer Core: 1.11.x or higher (included via Spring Boot Actuator)
  • Micrometer Tracing: 1.1.x or higher
  • Tracing Bridges: Brave 6.x or OpenTelemetry 1.x

Security Considerations

Log Security

  1. Disable in Production: Unless absolutely necessary, disable query response logging in production environments
  2. Log Retention: Configure appropriate log retention policies for logs containing vector store responses
  3. Access Controls: Restrict access to logs containing query responses to authorized personnel only
  4. Encryption: Ensure logs are encrypted at rest and in transit
  5. Audit: Regularly audit who accesses logs containing sensitive query data

Data Privacy Compliance

When enabling query response logging, consider:

  • GDPR: Query responses may contain personal data; ensure compliance with data protection regulations
  • HIPAA: Healthcare data in vector store responses may require additional protection
  • PCI DSS: Payment card data should never be logged
  • Internal Policies: Comply with organizational data handling policies

Recommended Production Configuration

spring:
  ai:
    vectorstore:
      observations:
        log-query-response: false  # Disabled for security

management:
  endpoints:
    web:
      exposure:
        include: health,metrics,prometheus  # Don't expose sensitive endpoints
  metrics:
    export:
      prometheus:
        enabled: true
  tracing:
    sampling:
      probability: 0.01  # Low sampling rate in production

logging:
  level:
    org.springframework.ai.vectorstore: INFO  # Minimal logging

Use custom handlers to log metadata without sensitive content:

@Bean
public ObservationHandler<VectorStoreObservationContext> productionHandler() {
    return new MetadataOnlyObservationHandler(); // Logs counts and timing, not content
}
tessl i tessl/maven-org-springframework-ai--spring-ai-autoconfigure-vector-store-observation@1.1.1
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/org.springframework.ai/spring-ai-autoconfigure-vector-store-observation@1.1.x