# Log API input and output By default the all APIs provided in this library does not log anything at all. To enable logging all API input/output using the `android.util.Log`, specify the `Logger` when constructing an instance of `Contacts`; ```kotlin val contactsApi = Contacts( context, logger = AndroidLogger() ) ``` > ℹ️ For more info on `Contacts` API setup, read [Contacts API Setup](./../setup/setup-contacts-api.md). Invoking the `find` or `commit` functions in query, insert, update, and delete APIs will result in the following output in the Logcat, ``` Query { rawContactsWhere: (account_name LIKE 'test@gmail.com' ESCAPE '\') AND (account_type LIKE 'com.google' ESCAPE '\') where: data1 LIKE '%@gmail.com%' ESCAPE '\' AND mimetype = 'vnd.android.cursor.item/email_v2' isRedacted: false // the rest is omitted for brevity } Query.Result { Number of contacts found: 2 First contact: Contact( id=46, rawContacts=[ RawContact( id=45, contactId=46, addresses=[Address(id=329, rawContactId=45, contactId=46, isPrimary=false, isSuperPrimary=false, type=WORK, label=null, formattedAddress=1200 Park Ave, street=1200 Park Ave, poBox=null, neighborhood=null, city=null, region=null, postcode=null, country=null, isRedacted=false)], emails=[ Email(id=318, rawContactId=45, contactId=46, isPrimary=false, isSuperPrimary=false, type=WORK, label=null, address=buzz.lightyear@pixar.com, isRedacted=false), Email(id=319, rawContactId=45, contactId=46, isPrimary=false, isSuperPrimary=false, type=HOME, label=null, address=buzz@lightyear.net, isRedacted=false) ], events=[ Event(id=317, rawContactId=45, contactId=46, isPrimary=false, isSuperPrimary=false, type=BIRTHDAY, label=null, date=EventDate(year=1995, month=10, dayOfMonth=22, isRedacted=false), isRedacted=false), Event(id=320, rawContactId=45, contactId=46, isPrimary=false, isSuperPrimary=false, type=ANNIVERSARY, label=null, date=EventDate(year=2022, month=0, dayOfMonth=1, isRedacted=false), isRedacted=false) ], // the rest is omitted for brevity ) ] ) isLimitBreached: false isRedacted: false } (10 milliseconds) ``` This is very useful during development. If you have any issues with the library, maintainers will most likely ask you for these logs to help debug your issues. > ℹ️ Notice that at the end, in parenthesis, the execution time of the `find` or `commit` operation > is provided 🙂 ## Custom loggers The library provides the `AndroidLogger`. However, if you want to use your own logging/tracking functions, you may create your own logger by providing an implementation of `Logger`. For example, to use [`Timber`](https://github.com/JakeWharton/timber) instead of `android.util.Log`, ```kotlin class TimberLogger : Logger { override val redactMessages: Boolean = true override fun log(message: String) { Timber.d(message) } } val contactsApi = Contacts( context, logger = TimberLogger() ) ``` ## Redacting log messages The messages that are logged may contain private user data (contact data). Depending on how you log these messages in production, you may end up violating privacy laws such as [GDPR](https://gdpr-info.eu) guidelines. To ensure that you are not violating any privacy laws in your production apps when using this library, make sure to set `Logger.redactMessages` to `true`. ```kotlin val contactsApi = Contacts( context, logger = AndroidLogger(redactMessages = true) ) ``` Redacted messages are not as useful when debugging so you should set it to `false` during development. A common way to redact messages in release builds but not debug builds is to, ```kotlin AndroidLogger(redactMessages = !BuildConfig.DEBUG) ``` For more info on redaction, read [Redact entities and API input and output in production](./../entities/redact-apis-and-entities.md).