Anıl Şenocak Anıl Şenocak
Yazılım Mühendisi
Cover image
2026-07-11 0 toplam yorum
Observability in Redis OM Spring: Implementing a Command Listener

Observability in Redis OM Spring: Implementing a Command Listener. Redis OM Spring simplifies building applications with Redis by providing powerful abstractions over RedisJSON and RediSearch. It allows developers to map Java objects to Redis documents using familiar Spring Data repositories.

While the abstraction is great for productivity, there are times when you need to see “under the hood.” That's where the CommandListener comes in.

Implementing the Command Listener

The CommandListener interface allows you to intercept search operations at two critical points: when a search starts and when it finishes.

Here is the implementation of a NoOpCommandListener that logs the exact FT.SEARCH commands executed against Redis:

@Component  
@Slf4j  
class NoOpCommandListener implements CommandListener {  
  
  @Override  
  public void searchStarted(final String indexName, final Query q, final FTSearchParams params) {  
    try {  
      // Accessing private \_queryString field via reflection to see the raw query  
      final Field field \= q.getClass().getDeclaredField("\_queryString");  
      field.setAccessible(true);  
      final String queryString \= (String) field.get(q);  
        
      log.info("FT.SEARCH Started - Index: '{}' Query: '{}'", indexName, queryString);  
    } catch (NoSuchFieldException | IllegalAccessException e) {  
      log.error("Command started on index: {} (unable to retrieve query string)", indexName);  
    }  
  }  
  
  @Override  
  public void searchFinished(final String indexName, final Query q, FTSearchParams params, final SearchResult searchResult) {  
    try {  
      final Field field \= q.getClass().getDeclaredField("\_queryString");  
      field.setAccessible(true);  
      final String queryString \= (String) field.get(q);  
        
      log.info("FT.SEARCH Finished - Index: '{}' Query: '{}' - Total results: {}",   
               indexName, queryString, searchResult.getTotalResults());  
    } catch (NoSuchFieldException | IllegalAccessException e) {  
      log.error("Command finished on index: {} (unable to retrieve query string)", indexName);  
    }  
  }  
}

Key Technical Highlights:

  1. Command Interception: By implementing CommandListener and marking it as a @Component, Redis OM Spring automatically picks it up and routes command events through it.
  2. Reflection for Deep Inspection: The Query object in the Jedis client encapsulates the query string. To log the exact command for debugging, we use reflection to access the internal _queryString field.
  3. Performance Insights: The searchFinished method provides access to the SearchResult, allowing you to track how many results are being returned for specific queries.

Real-World Usage: The Person API

To see this in action, consider a simple application managing Person documents.

The Model

We use @Document for RedisJSON mapping and @TextIndexed / @TagIndexed for search indexing.

@Data  
@Document  
public class Person {  
  @Id  
  private Long id;  
  
  @TextIndexed  
  private String firstName;  
  
  @TextIndexed  
  private String lastName;  
  
  @TagIndexed  
  private String email;  
}
public interface PersonRepository extends RedisDocumentRepository<Person, Long> {  
  List<Person> findByLastNameAndFirstName(String lastName, String firstName);  
  Person findByEmail(String email);  
}

When you call an endpoint like /api/persons/name/Doe/John, the NoOpCommandListener will produce logs similar to:

INFO  NoOpCommandListener - FT.SEARCH Started - Index: 'com.redis.om.documents.domain.PersonIdx' Query: '@lastName:Doe @firstName:John'  
INFO  NoOpCommandListener - FT.SEARCH Finished - Index: 'com.redis.om.documents.domain.PersonIdx' Query: '@lastName:Doe @firstName:John' - Total results: 1

Conclusion

Implementing a CommandListener in Redis OM Spring is a powerful way to gain observability into your data layer. Whether you’re debugging complex queries or monitoring search performance, having a window into the commands being sent to Redis is invaluable.

You can find the full demo project here.
Happy coding with Redis!

Yorumlar
Henüz yorum yok. İlk yorumu sen yaz.
Yorum Bırak
Adınız (isteğe bağlı)
Yorumunuzu yazın...
0/500