{"id":90870,"date":"2021-05-10T21:22:38","date_gmt":"2021-05-10T21:22:38","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=90870"},"modified":"2021-05-10T21:22:38","modified_gmt":"2021-05-10T21:22:38","slug":"setting-up-a-kafka-test-environment-with-kafdrop","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/setting-up-a-kafka-test-environment-with-kafdrop\/","title":{"rendered":"Setting up a Kafka test environment with Kafdrop"},"content":{"rendered":"<p>The\u00a0<a href=\"https:\/\/www.red-gate.com\/simple-talk\/dotnet\/net-development\/using-apache-kafka-with-net\/\">first article<\/a>\u00a0of this series on Apache Kafka explored very introductory concepts around the event streaming platform, a basic installation, and the construction of a fully functional application made with .NET, including the production and consumption of a topic message via command line.<\/p>\n<p>From a daily life standpoint, it\u2019s challenging to manage Kafka brokers, partitions, topics, producers, and consumers all via command line. An interface would be quite helpful.<\/p>\n<p>There is a ton of available options for managing your Kafka brokers for web UI applications. Perhaps\u00a0<a href=\"https:\/\/www.confluent.io\/product\/confluent-platform\/gui-driven-management-and-monitoring\/\">Confluent\u2019s version<\/a>\u00a0is one of the most complete, although it is part of a paid combo for mostly enterprise means.<\/p>\n<p>Amongst the myriad of open-source options, <a href=\"https:\/\/github.com\/obsidiandynamics\/kafdrop\">Kafdrop<\/a> stands out for being simple, fast, and easy to use. It is an open-source web project that allows you to view information from Kafka brokers as existing topics, consumers, and even the content of messages sent.<\/p>\n<p>This article explores creating a more flexible test environment to work alongside the .NET app built in the previous article. This way, you\u2019ll have more powerful tools to understand what\u2019s happening with your topics.<\/p>\n<h2>Getting Ready<\/h2>\n<p>The previous article made use of the <em>wurstmeister<\/em> Docker images. Because of the maturity of Confluent Docker images, this article will migrate the docker-compose to make use of its images. They\u2019re called <a href=\"https:\/\/github.com\/confluentinc\">confluentinc<\/a>.<\/p>\n<p>Take a look at the updated content of the <em>docker-compose.yml<\/em> now:<\/p>\n<p><strong>Listing 1. Updating the docker-compose.yml file<\/strong><\/p>\n<pre class=\"lang:none theme:none\">version: '3'\r\nservices:\r\n  zookeeper:\r\n    image: confluentinc\/cp-zookeeper:latest\r\n    networks: \r\n      - broker-kafka\r\n    environment:\r\n      ZOOKEEPER_CLIENT_PORT: 2181\r\n      ZOOKEEPER_TICK_TIME: 2000\r\n  kafka:\r\n    image: confluentinc\/cp-kafka:latest\r\n    networks: \r\n      - broker-kafka\r\n    depends_on:\r\n      - zookeeper\r\n    ports:\r\n      - 9092:9092\r\n    environment:\r\n      KAFKA_BROKER_ID: 1\r\n      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181\r\n      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT:\/\/kafka:29092,PLAINTEXT_HOST:\/\/localhost:9092\r\n      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT\r\n      KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT\r\n      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1\r\n  kafdrop:\r\n    image: obsidiandynamics\/kafdrop:latest\r\n    networks: \r\n      - broker-kafka\r\n    depends_on:\r\n      - kafka\r\n    ports:\r\n      - 19000:9000\r\n    environment:\r\n      KAFKA_BROKERCONNECT: kafka:29092\r\nnetworks: \r\n  broker-kafka:\r\n    driver: bridge  <\/pre>\n<p>The first thing is to update its version. That\u2019s a good way to ensure that your Docker files will also keep versioning through the many changes they may suffer.<\/p>\n<p>You\u2019ll keep the images of Kafka and Zookeeper, although the image sources are different this time. If you\u2019re willing to keep working with the previous ones, that\u2019s ok too. Just make sure to consult the vendor-specific settings that may be required for a broker as such.<\/p>\n<p>The new network called <code>broker-kafka<\/code> will be responsible for keeping the communication among the three containers.<\/p>\n<p>Finally, at the end of the listing, you get to see the Kafdrop-related container settings, which are set up with a specific port. This is the same port you\u2019ll use later to access the UI. Feel free to change it as you wish.<\/p>\n<p>Before you can rerun the docker-compose commands, you need to make sure that the previous images aren\u2019t running nor installed on your machine. The easiest way is through Docker Desktop. Open it and make sure to delete all the containers from the previous article whether they\u2019re running or not.<\/p>\n<p>Another way to check this out is via command line:<\/p>\n<pre class=\"lang:none theme:none\">docker-compose ps<\/pre>\n<p>Now rerun the docker-compose command to re-download everything and build the images from scratch:<\/p>\n<pre class=\"lang:none theme:none\">docker-compose up -d<\/pre>\n<p>Wait until the command downloads all the images from the internet, as shown in Figure 1.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"716\" height=\"636\" class=\"wp-image-90871\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/05\/word-image-43.png\" \/><\/p>\n<p><strong>Figure 1.<\/strong> <strong>Downloading new Docker images<\/strong><\/p>\n<p>You may see that the download was successful, and the images started up, as shown in Figure 2.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"515\" height=\"72\" class=\"wp-image-90872\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/05\/word-image-44.png\" \/><\/p>\n<p><strong>Figure 2. New images downloaded and started<\/strong><\/p>\n<p>To check if the network was created, run the following command:<\/p>\n<pre class=\"lang:none theme:none\">docker network ls<\/pre>\n<p>That\u2019ll print the list of networks including the newly created <em>broker-kafka<\/em> (Figure 3).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"434\" height=\"105\" class=\"wp-image-90873\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/05\/word-image-45.png\" \/><\/p>\n<p><strong>Figure 3. Docker network check<\/strong><\/p>\n<p>To check if the running images include the new Kafdrop, run the command <code>docker ps<\/code> and compare the results with Figure 4.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1153\" height=\"88\" class=\"wp-image-90874\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/05\/word-image-46.png\" \/><\/p>\n<p><strong>Figure 4.<\/strong> <strong>Checking the running images via <em>docker ps<\/em><\/strong><\/p>\n<p>Finally, Docker Desktop is the easiest way to check that out. Figure 5 shows how your images should look.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"747\" height=\"333\" class=\"wp-image-90875\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/05\/word-image-47.png\" \/><\/p>\n<p><strong>Figure 5.<\/strong> <strong>Newly created Docker images on Docker Desktop<\/strong><\/p>\n<p>That visualization also allows seeing the port in which each image is running. If you click any of the images, Docker Desktop will display the logs of that container live.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"2500\" height=\"1590\" class=\"wp-image-90876\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/05\/word-image-48.png\" \/><\/p>\n<p><strong>Figure 6.<\/strong> <strong>Watching Docker image logs<\/strong><\/p>\n<h2>Exploring Kafdrop<\/h2>\n<p>With the configs set, Kafdrop is started at the <a href=\"http:\/\/localhost:19000\/\">http:\/\/localhost:19000\/<\/a> address. Figure 7 shows how the interface looks.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1380\" height=\"877\" class=\"wp-image-90877\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/05\/word-image-49.png\" \/><\/p>\n<p><strong>Figure 7.<\/strong> <strong>Kafdrop cluster overview<\/strong><\/p>\n<p>The information is segregated into the broker servers, total topics, and partitions. Kafka is designed to work in a distributed manner, which means that it is usually set up to be within a distributed cluster with more than one bootstrap server. While working locally, however, there\u2019s only one server displayed here.<\/p>\n<p>Also, since the previous Kafka images are removed, there\u2019s no topic available. To change that, start the producer and consumer applications from the previous article.<\/p>\n<p>Go ahead and do that. Once you finish the startup, go back to the Kafdrop page and reload it. You will see a result similar to that shown in Figure 8.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"2500\" height=\"1590\" class=\"wp-image-90878\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/05\/word-image-50.png\" \/><\/p>\n<p><strong>Figure 8.<\/strong> <strong>Total topics increased by 1 + <em>__consumer_offsets<\/em> topic<\/strong><\/p>\n<p>Since Kafka keeps the state of the messages in storage, the consumer offsets topic is important to keep track of the sequential order in which the messages arrived at the topics.<\/p>\n<p>That\u2019s a way Kafka uses to know where it has stopped from the last time in case the infrastructure that holds the broker shuts down, for example.<\/p>\n<p>This tutorial won\u2019t focus on them, however. As you may guess, besides both producer and consumer are up, the <em>simpletalk_topic<\/em> is still not visible on the list. That happens because it needs to have some interaction with the topic, such as a new message being sent. That\u2019s when Kafka creates the topic in case it still doesn\u2019t exist.<\/p>\n<p>Send a new message to the topic and see what happens:<\/p>\n<pre class=\"lang:none theme:none\">curl -H \"Content-Length: 0\" -X POST \"http:\/\/localhost:51249\/api\/kafka?message=Hello,kafka!\" -k<\/pre>\n<p>The command you enter may be slightly different depending on your setup. The command line window running the Kafka Producer program should tell you what to enter here. When you refresh the Kafdrop page, Figure 9 shows how it must look.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1380\" height=\"877\" class=\"wp-image-90879\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/05\/word-image-51.png\" \/><\/p>\n<p><strong>Figure 9.<\/strong> <strong>New topic added to the topics list<\/strong><\/p>\n<p>Nice, isn\u2019t it? If you click the <em>simpletalk_topic<\/em> link, you\u2019ll be redirected to the page shown in Figure 10.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1380\" height=\"877\" class=\"wp-image-90880\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/05\/word-image-52.png\" \/><\/p>\n<p><strong>Figure 10.<\/strong> <strong>Visualizing simpletalk_topic on Kafdrop<\/strong><\/p>\n<p>Among the information provided on this page, the most important is related to the number of available messages for the topic. Kafdrop is a great way to visualize problems in a production environment arising from applications that produce and consume from this topic.<\/p>\n<p>If you click the <em>View Messages<\/em> button on the top of the page, you\u2019ll be redirected to a second page, as shown in Figure 11.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1380\" height=\"486\" class=\"wp-image-90881\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/05\/word-image-53.png\" \/><\/p>\n<p><strong>Figure 11.<\/strong> <strong>Visualizing the messages of a topic<\/strong><\/p>\n<p>You may click the <em>View Messages<\/em> button once more to be able to see the list of messages. Remember that this is just a visualization; it doesn\u2019t mean that a consumer or a group of consumers have consumed the message already.<\/p>\n<p>To see this, make sure that your consumer project has printed the message stating that it has committed the topic consumption. You may need to restart the consumer project to get this to appear. Then, get back to the topic details page, and you may see it as shown below.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1380\" height=\"877\" class=\"wp-image-90882\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/05\/word-image-54.png\" \/><\/p>\n<p><strong>Figure 12. Visualizing new consumers attached to a topic<\/strong><\/p>\n<p>As you see, a new consumer whose group id is \u201c<em>st_consumer_group<\/em>\u201d is now tied to this topic. If you click it, a more detailed version of the consumer group will show up, as shown in Figure 13.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1380\" height=\"877\" class=\"wp-image-90883\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/05\/word-image-55.png\" \/><\/p>\n<p><strong>Figure 13.<\/strong> <strong>Details about a specific consumer group<\/strong><\/p>\n<p>The <em>Last Offset<\/em> column states the current latest offset for the entire topic, regardless of who consumed its messages. The <em>Consumer Offset<\/em>, in turn, stands for the offset at which the current consumer group is at. The value 1 means that all the published messages were already consumed by this consumer.<\/p>\n<p>If you wish, you\u2019ll be able to create a new topic via Kafdrop by clicking the <em>+ New<\/em> button located on the homepage. This will enable the following screen for you to finalize the creation.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"1186\" height=\"1054\" class=\"wp-image-90884\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/05\/word-image-56.png\" \/><\/p>\n<p><strong>Figure 14.<\/strong> <strong>Creating a new topic with Kafdrop<\/strong><\/p>\n<h2>Swagger Integration<\/h2>\n<p>If you wish to document your Kafka topics, consumers, etc., in an API-related way, Kafdrop also provides you with integration with <a href=\"https:\/\/swagger.io\/\">Swagger<\/a>.<\/p>\n<p>Towards the endpoint <a href=\"http:\/\/localhost:19000\/v2\/api-docs\">localhost:19000\/v2\/api-docs<\/a>, you\u2019ll be able to see all the Swagger 2.0 Open Specification JSON that you can use to document and run endpoints on your Kafdrop environment. That\u2019s another alternative for those who don\u2019t want to explicitly allow access to Kafdrop UI for all users.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"2500\" height=\"1590\" class=\"wp-image-90885\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/05\/word-image-57.png\" \/><\/p>\n<p><strong>Figure 15.<\/strong> <strong>Swagger API docs for Kafdrop<\/strong><\/p>\n<p>If you\u2019re used to working with micro metrics, and since Kafdrop is made with Spring and Java, it also provides an endpoint for the app metrics at <a href=\"http:\/\/localhost:19000\/actuator\">localhost:19000\/actuator<\/a>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"2398\" height=\"1196\" class=\"wp-image-90886\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2021\/05\/word-image-58.png\" \/><\/p>\n<p><strong>Figure 16.<\/strong> <strong>Kafdrop micro metrics via Actuator<\/strong><\/p>\n<p>That\u2019s very useful when you already have automatic monitor tools that check the health of your infrastructure apps as well as other factors and alarm based on failing scenarios.<\/p>\n<h1>Setting Up a Kafka Test Environment with Kafdrop<\/h1>\n<p>Kafdrop is a great option for allowing a better-integrated environment not only for testing purposes but also for development and operational activities within your company. With it, you\u2019re able to visualize your entire Kafka cluster, including the topics, consumer groups, messages, offsets, and more.<\/p>\n<p>How about you? Have you used any similar tool in the past? Let me know in the comments about your experience with them.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Kafdrop is n open source project that allows you to view information from Kafka brokers. In this article, Diogo Souza explains setting up a Kafka test environment with Kafdrop.&hellip;<\/p>\n","protected":false},"author":320401,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143538,53],"tags":[143553,143552,5134],"coauthors":[60461],"class_list":["post-90870","post","type-post","status-publish","format-standard","hentry","category-dotnet-development","category-featured","tag-kafdrop","tag-kafka","tag-sql-prompt"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/90870","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/320401"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=90870"}],"version-history":[{"count":2,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/90870\/revisions"}],"predecessor-version":[{"id":90888,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/90870\/revisions\/90888"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=90870"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=90870"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=90870"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=90870"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}