Share via

Log4Net – Write logs to a second file only when a failure occurs (C# 10)

Alin A 25 Reputation points
2026-03-07T10:38:25.1833333+00:00

Hi,

I am using Log4Net in my system.

Currently, the logs are written only to the administrator’s log location and not to the user who runs the system.

What do you suggest ?

I though a solution so that whenever a failure occurs, the log will also be copied to the user’s location using MemoryAppender flush.

  1. Admin log only (classic file logging).
  2. User log only on failure (MemoryAppender flush).
  3. NullLogger mode (disable all logging).

My current Log.

Log.txt

Extension to Log to support this problem , do you see problem if this the right solution?

Log.txt

Thanks in advance,User's image

Thanks in advance,

Developer technologies | C#
Developer technologies | C#

An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.

{count} vote

5 answers

Sort by: Most helpful
  1. Danny Nguyen (WICLOUD CORPORATION) 6,455 Reputation points Microsoft External Staff Moderator
    2026-03-09T10:35:02.0233333+00:00

    Hi @Alin A.

    From your post, it sounds like you want to always log to the admin file, but only create/write a separate user log when an error happens, and you’re asking if using a MemoryAppender and flushing it on the first failure is a good approach. The idea is sound. Buffer some recent log messages in memory, and when the first error happens, dump them to a user file so the user can send it to support.

    But I see a few problems to watch out for:

    1. Be careful configuring log4net in code

    BasicConfigurator.Configure(...) changes the global log4net setup. If you call your SetAdminFile() / SetAdminAndUserFailure() more than once (restart logging, tests, etc.), you can end up with multiple appenders and duplicated log lines. You should reset/reconfigure the repository (or let the host configure log4net and only swap your adapter).

    1. Make the “flush once” thread-safe

    If two threads log an error at the same time, you might flush twice. Use Interlocked or a lock around the flush.

    1. Memory can grow forever

    If the app runs a long time and no error happens, MemoryAppender can keep growing. Usually you want to keep only the last N messages (a small ring buffer), not everything.

    1. Your example doesn’t match the code after the first error

    Right now you flush the buffered messages once, but after that you do NOT keep writing new Info/Warn/Debug to the user file. That’s fine if you only want “pre-error context”, but then say that clearly. If you want “after error, keep logging to the user file too”, you need to add that behavior.

    1. Your ‘UserFailureOnly’ mode doesn’t buffer

    UserLogOnlyAdapter ignores Info/Warn/Debug, so the user won’t get the “what happened before the error” context. If you want that, it also needs buffering + flush.

    Overall: the pattern is good, just limit the buffer size, make flush thread-safe, and be careful with global log4net configuration.

    If you found my response helpful or informative, I would greatly appreciate it if you could follow this guidance provide feedback. Thank you. 


  2. Deleted

    This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.


    Comments have been turned off. Learn more

  3. Deleted

    This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.


    Comments have been turned off. Learn more

  4. Deleted

    This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.


    Comments have been turned off. Learn more

  5. Q&A Assist
    2026-03-07T10:38:46.83+00:00
    AI generated content. This question contains an answer created with AI from Q&A Assist. Learn more

    Use of a MemoryAppender that is flushed only when a failure occurs is a valid pattern, but it should be implemented with attention to log levels, security, and resource usage.

    Key points to consider:

    1. Log only what is needed for the user
      • Avoid copying full admin logs to the user’s location. Admin logs can contain sensitive data or internal details that should not be exposed.
      • Configure the user‑side flush to include only messages at Error (or Warning/Critical) level that are relevant to troubleshooting from the user’s perspective.
      • In .NET logging guidance, Trace and Debug are not recommended for production because of volume and potential sensitivity; keep those in the admin log only.
      • See the log level guidance for how to choose which events to capture and flush to the user log.
    2. Keep the admin log independent
      • Continue to use the existing file appender for the administrator log as the primary, always‑on log.
      • The MemoryAppender should be an additional appender that buffers events in memory; it should not interfere with the admin file appender.
      • This matches the pattern where multiple providers/appender targets are configured and each receives the same log events.
    3. Implement failure‑triggered flushing
      • Configure the logger so that all events go to both the admin file appender and the MemoryAppender.
      • On detection of a failure (for example, when logging an error or critical event), read the buffered events from the MemoryAppender and write them to a user‑specific file.
      • Limit what is flushed based on log level (for example, only Information and above, or only Warning/Error/Critical) to avoid excessive or sensitive data.
      • This aligns with log‑buffering guidance: buffer logs in memory and selectively emit them based on runtime conditions, while being mindful of memory usage.
    4. Control memory usage and log size
      • A MemoryAppender that accumulates logs for a long session can grow large. Apply limits (for example, maximum number of events or time window) and drop older entries when the limit is reached.
      • This follows buffering best practices: set appropriate buffer size limits and, if applicable, use per‑request or per‑operation buffers so that a single long‑running session does not consume unbounded memory.
    5. Provide a Null/disabled mode
      • A NullLogger or configuration that sets log level to None is a reasonable way to disable logging when required (for example, in performance‑critical or privacy‑sensitive scenarios).
      • Ensure that when logging is disabled, both the admin file appender and the MemoryAppender are effectively bypassed so that no data is written or buffered.
    6. Security considerations for the user log
      • Ensure that the user log location is secured with appropriate file system permissions so that only the intended user (or support personnel) can read it.
      • Validate any data written to the log to avoid misleading or untrusted content.
      • Avoid logging secrets, passwords, or other highly sensitive information in either admin or user logs.

    If the current extension:

    • Keeps the admin file appender unchanged,
    • Uses a bounded MemoryAppender that is flushed only on error/critical events,
    • Filters what is flushed by log level and content,
    • And supports a configuration switch for NullLogger mode,

    then it is an appropriate and robust solution for writing logs to a second file only when a failure occurs.


    References:

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.