<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">
	<channel>
		<title>Flutter Logging Made Easier with Loggy Library | Infinum</title>
		<atom:link href="https://infinum.com/blog/logging-in-flutter/feed/" rel="self" type="application/rss+xml" />
		<link>https://infinum.com/blog/logging-in-flutter/</link>
		<description>Building digital products</description>
		<lastBuildDate>Fri, 17 Apr 2026 13:59:15 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>

					<item>
				<image>
					<url>7858https://infinum.com/uploads/2021/06/logging-in-flutter-0.webp</url>
				</image>
				<title>Better Logging in Flutter with Loggy Library</title>
				<link>https://infinum.com/blog/logging-in-flutter/</link>
				<pubDate>Wed, 16 Jun 2021 16:15:00 +0000</pubDate>
				<dc:creator>Luka Knezić</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/logging-in-flutter/</guid>
				<description>
					<![CDATA[<p>Never again overlook critical messages.</p>
<p>The post <a href="https://infinum.com/blog/logging-in-flutter/">Better Logging in Flutter with Loggy Library</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-196"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-92">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-95"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-93">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-94'
	>
	<strong>Flutter logging</strong> proved inadequate for all our requirements as we started using <a href="https://infinum.com/mobile-web-apps/flutter/">Flutter more extensively in larger projects</a> at Infinum.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-98"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-96">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-97'
	>
	<a href="https://infinum.com/blog/flutter-vs-native/">Flutter</a> had a great year in 2020 with over half a million developers using it daily. It has surpassed react-native, linux, and vscode by the number of stars on github.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-99">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-100'
	>
	Is a logger really necessary?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-104"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-102">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-103'
	>
	Logging is a really important tool for any developer and any application. It can make debugging time significantly shorter and help developers figure out sooner what’s going on in the app.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-107"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-105">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-106'
	>
	Using the <strong>Flutter logger</strong> properly can be highly valuable when an app is in the production environment. It allows developers to analyze user actions and understand the cause of a problem.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-110"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-108">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-109'
	>
	Problems with Flutter logging</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-113"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-111">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-112'
	>
	As logging in Flutter is very bland by default, developers mostly rely on print. The main problem with print is that all messages are treated the same way. There is no distinction between info and critical log messages. <strong>Critical messages are easily overlooked</strong>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-116"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-114">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-115'
	>
	There is also no ability to turn logging off when building a production version. That can be a big security concern since all prints would be visible and easily accessible.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-119"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-117">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-118'
	>
	Possible solutions to Flutter logging</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-122"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-120">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-121'
	>
	We noticed this problem when we were developing an app with complex navigation with socket communication. Often, <strong>socket messages would overflood our console</strong>, and then removing them would take a while, and debugging if something went wrong in communication would take even longer.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-125"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-123">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-124'
	>
	We wanted a way to toggle logs depending on the feature we were working on, so we set up the following criteria for the logger. Firstly, we wanted to have multiple logger levels and types, because filtering just by levels is not sufficient. In addition to that, we would need filtering and the ability to easily toggle logging.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-128"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-126">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-127'
	>
	We would also try to <strong>find a logger that has as little setup as possible</strong> in order to get as much data as possible.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-131"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-129">
	<h3	class='typography typography--size-36-text js-typography block-heading__heading'
	data-id='es-130'
	>
	The hunt for libraries</h3></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-134"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-132">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-133'
	>
	<strong>We tried almost every logging library that existed at the time</strong>. Even though all of them had implemented our criteria on multiple levels, none of them fitted all the criteria.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-137"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-135"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-136">
	<picture class="image__picture block-media__image-picture">
								
			<source
				srcset=https://infinum.com/uploads/2021/06/logging-in-flutter-1-1400x995.webp				media='(max-width: 699px)'
				type=image/webp								height="995"
												width="1400"
				 />
												<img
					src="https://infinum.com/uploads/2021/06/logging-in-flutter-1.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1137"
															width="1600"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-140"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-138">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-139'
	>
	<strong>Filter by type was the hardest requirement to fulfil</strong> and it was either impossible or very difficult to implement. But we persisted on fulfilling that criteria as it would allow us to turn loggers on and off for a single feature, without affecting other loggers.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-143"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-141">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-142'
	>
	Filtering only by level would again lead us to the same path, and further down in app development more and more messages would become error or warning levels in order to become visible.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-146"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-144">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-145'
	>
	Some of the libraries had nice extra features which we wanted to include, but since none of them met all of our requirements, the only reasonable decision was to make our own Flutter logging library. Cue <a href="https://github.com/infinum/floggy">Flutter Loggy</a>!</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-149"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-147">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-148'
	>
	Mixins to the rescue</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-152"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-150">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-151'
	>
	We decided to use mixins from dart to achieve quick setup, while keeping different types separated. Using mixins has a lot of practical usages, so we wanted to see if they could help us with our logging problems.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-155"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-153">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-154'
	>
	Since mixins can get calling class name, we used that to generate tags for logs, and we could make more types by making different mixins for different layers. Having multiple types would allow us to separate loggers for different layers of the application, which can be easily filtered.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-158"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-156">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-157'
	>
	We built the logger with mixins, and filtering them worked as expected – making new types was simple, and Loggy would come with 2 types – <code>UiLoggy</code> and <code>NetworkLoggy</code>. They are a great starting point and good examples for creating custom types later.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-161"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-159">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-160'
	>
	To use Loggy, simply add <code>Loggy.initLoggy()</code> before <code>runApp()</code>, and add <code>with UiLoggy</code> in any class where you need Loggy. That being done, it’s now time to log the messages <code>loggy.debug</code>, <code>loggy.info</code>, <code>loggy.warning</code> or <code>loggy.error</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-164"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-162"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-163">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2021/06/logging-in-flutter-2.webp"
					class="image__img block-media__image-img"
					alt=""
										height="961"
															width="1212"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-167"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-165">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-166'
	>
	The library can be configured with <code>initLoggy</code>, from where it’s possible to add filters, levels and printer for logger.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-170"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-168">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-169'
	>
	With different types of logging and a habit of using networking in pretty much every app, we made an interceptor for the most popular networking library Dio. Dio interceptor can attach to Dio instance and log requests and responses.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-173"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-171"
	 data-media-type='video'>

	<div class="video__wrapper" data-id="es-172">
		<video
		class="video block-media__video js-video js-block-media-video video--cursor-takeover-use"
		 loop autoplay playsinline muted preload='metadata'>
		<source  src='https://infinum.com/uploads/2021/06/loggy_dio_gif.mp4' type='video/mp4' />	</video>
	</div></div></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-176"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-174">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-175'
	>
	This interceptor is useful because of ║, ╔ and ╚. Using these symbols, it is possible to set up the console to collapse all lines that contain them. This way, we will see the request and the response code, but the request body will be collapsed and can be expanded to show more details.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-179"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-177">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-178'
	>
	Problems solved with Flutter Loggy</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-182"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-180">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-181'
	>
	With Loggy, all of the problems we had before were gone. Now we can <strong>easily set up different printers</strong>, eg. instead of sending events to console the printer can send events to crashlytics for production builds or just disable logging completely.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-185"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-183">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-184'
	>
	When it comes to types, <strong>it’s simple to set up different ones</strong>, allowing for easy filtering by type in order to decide which to include in production builds.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-188"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-186">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-187'
	>
	Finally, <strong>using Loggy inside the app is convenient</strong> – simply by adding <code>with UiLoggy</code> and logging something a lot more info becomes available, and it’s possible to control priority or easily disable it without actually removing it.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-191"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-189">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-190'
	>
	We also managed to clear out our console while actually logging more stuff about the request, since they show up collapsed they take just 1 line of space, but they can be expanded to show whole request details.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-194"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-192">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-193'
	>
	All in all, we are pleased with the results, so <a href="https://github.com/infinum/floggy">give Loggy a try</a> and let us know whether it made your Flutter logging easier!</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/logging-in-flutter/">Better Logging in Flutter with Loggy Library</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>