There is a feature that is now deprecated and going to be removed. Adding a logging statement, observed by some alerting mechanism, can help finding out whether the feature is still being actively used and upgrade the clients that do so.

Although not necessarily technically important for the diagnosis, I wonder what would be the appropriate log level in a semantical sense.

  • INFO, because it’s just an information. The use of the feature does not cause any potential harm.
  • WARNING, because it’s necessary to eventually upgrade all clients. After upgrade, this will become an error.

Or create a custom level, if supported by the language/framework/ecosystem?

4 Answers 4


In my past experience, I usually use the lowest level enabled in production environment (INFO?). Then, prefix log msg with keyword tag, say DEPRECATED. In log monitor/alert tool (can't suggest any tool, as I only experienced with in-house tool), specify the keyword tag as match condition. I try not use WARNING because those log messages could distract my attention from real issue.

--- update 2/28

On second thought, my approach may not work in all org because we use INFO for non-errors that need tracking, other non-error logs go to either VERBOSE or DEBUG. If your company's log strategy is different, it might end up having huge amount of production log.


I'm using NLog as an example here as it's the logging framework I most often use. I expect similar frameworks to have similar features.

WARNING, because it’s necessary to eventually upgrade all clients. After upgrade, this will become an error.

I see your reasoning here, and the generally used definition on what constitues a warning can arguably apply here. But I would only resort to this if it's a single warning (e.g. during startup) rather than a continual warning being spammed in the logs whenever the feature is being used.

The problems from spamming these messages (i.e. distracting from actual events) are more detrimental than the added benefit of having upgraded this message from a lower level to WARNING.

INFO, because it’s just an information.

I can somewhat follow this reasoning, but in my opinion it belongs on even lower levels (DEBUG/TRACE). This is effectively information for the developer, which is essentially what DEBUG/TRACE are built for. INFO messages are intended for developers and non-developers alike, and this message is only relevant to the developers.

Or create a custom level, if supported by the language/framework/ecosystem?

I would opt for this where available. The new level doesn't necessarily have to be on a level on its own though it certainly can be, where possible and deemed relevant).
NLog for example allows you to add different levels which behave similar to another level, but have a different name. For example, you could create a DEPRECATED level which is functionally equivalent to DEBUG.

This means that when you use level range filtering (e.g. a logger that captures from TRACE to INFO), DEPRECATED messages will always be bundled together with DEBUG messages, but the log messages themselves are labeled differently so you can quickly differentiate one from the other, e.g. if you're aware of the deprecated messages and want to filter them out for the time being.

In absence of a framework that allows you to define custom log levels, you can still resort to tagging your log messages, whether it's by prepending the DEPRECATED keyword to the log message or registering it in a custom log property (NLog allows you to pass additional values, which you could store in a separate field if you want to)



Add a metric to your server which records the volume/rate of calls to all methods.

Or even better the client version connecting.

You can then report on usage as required.

Logging is unsuitable for this as you will not want to run production code with logging less than Error and its not an Error

  • A problem I see with metrics is that AFAIK (at least in case of Prometheus) it doesn’t support metadata. Like that I can measure that the deprecated feature is used, but not by whom.
    – Glutexo
    Feb 28, 2020 at 9:44
  • you could use labels maybe? prometheus.io/docs/practices/naming working out who is using which version of a client might be better done as part of the authentication call though. Or if you are splitting the version at network level via a load balancer you could see the IP addresses there
    – Ewan
    Feb 28, 2020 at 10:15


This is not an useful information at runtime to the user.

A good practice is to inform this in the own code, at the programming time, as sample in C# we have a directive to this:


You can also add documentation to your code advising about its deprecation and suggesting a replace function to use instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.