log4net không hoạt động


123

Này, tôi có cấu hình này trong web.config của mình

<log4net>
    <appender name="LogFileAppender" type="log4net.Appender.FileAppender">
        <param name="File" value="mylog.log" />
        <param name="AppendToFile" value="true" />
        <layout type="log4net.Layout.PatternLayout">
            <param name="Header" value="" />
            <param name="Footer" value="" />
            <param name="ConversionPattern" value="%d [%t] %-5p %m%n" />
        </layout>
    </appender>
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
        <layout type="log4net.Layout.PatternLayout">
            <param name="Header" value="[Header]\r\n" />
            <param name="Footer" value="[Footer]\r\n" />
            <param name="ConversionPattern" value="%d [%t] %-5p %m%n" />
        </layout>
    </appender>
    <root>
        <level value="DEBUG" />
        <appender-ref ref="LogFileAppender" />
        <appender-ref ref="ConsoleAppender" />
    </root>
</log4net>

nhưng log4net không hoạt động. Dự án của tôi biên dịch tốt và tôi cũng không gặp lỗi khi gỡ lỗi. Những dòng mà tôi yêu cầu log.debug("somemessage")chạy tốt, nhưng tôi không thể tìm thấy mylog.logtệp, vậy nó ở đâu?


Hãy chắc chắn để kiểm tra điều này quá: stackoverflow.com/a/24617269/114029
Leniel Maccaferri

Câu trả lời:


298

Một điểm cần lưu ý cho loại điều này là đảm bảo thêm XmlConfiguratorthuộc tính vào assembly bằng cách đặt dòng sau vào AssemblyInfo.cs:

[assembly: log4net.Config.XmlConfigurator]

Nếu không, log4net sẽ không bao giờ kích hoạt.


5
Phương pháp này đã từng hoạt động trong dự án của tôi, nhưng bằng cách nào đó nó đã ngừng hoạt động. Tôi đã phải sử dụng phương pháp này stackoverflow.com/a/1479343/193634 để làm cho nó hoạt động trở lại.
Rosdi Kasim

Tôi vừa thử lại và nó hoạt động tốt. Nhiều khả năng là bạn không tham chiếu / tải assembly có chứa AssemblyInfongay như bạn nghĩ.
Kirk Woll

Đối với những người sử dụng ELMAH appender, đây là cách để đi. Tôi đã có 'log4net.Config.XmlConfigurator.Configure ();' trong global.asax.cs và nó hoạt động tốt đối với trình đính kèm tệp nhưng không hoạt động tốt đối với trình phụ lục ELMAH.
user3885927

Tôi đã đánh dấu chọn câu trả lời này và nhận thấy mình cần phải chỉnh sửa nó với `[assembly: log4net.Config.XmlConfigurator (Watch = true)] '
David Savage

49

Tôi đoán rằng log4net hoàn toàn không ghi nhật ký hoặc tệp không kết thúc như bạn mong đợi.

Thứ nhất, bạn đã thực sự gọi

XmlConfigurator.Configure()

bất cứ nơi nào trong mã của bạn? Nếu đoạn mã xml ở trên nằm trong tệp cấu hình ứng dụng, thì lệnh gọi này sẽ thực hiện thủ thuật. Nếu đoạn mã xml nằm trong tệp của chính nó, bạn sẽ cần sử dụng .Configure(string)quá tải dẫn đến đường dẫn đến tệp. Nếu không có lệnh gọi này (hoặc rõ ràng là thuộc tính mức lắp ráp được đề cập bởi Kirk Woll), thì log4net sẽ không ghi nhật ký được.

Nếu bạn tin rằng mọi việc đã xong và log4net sẽ được ghi lại, thì có lẽ bạn nên đặt một đường dẫn đủ điều kiện vào cho tệp nhật ký trong khi gỡ lỗi thêm. Điều đó sẽ giúp bạn chắc chắn rằng tệp sẽ ở đâu.


33

Có một gotcha nhỏ khác, xem tại đây: http://logging.apache.org/log4net/release/manual/configuration.html#dot-config

các [assembly: log4net.Config.XmlConfigurator]phương pháp không làm việc với App.config. Nếu bạn định cấu hình log4net từ app.config, bạn phải sử dụng log4net.Config.XmlConfigurator.Configure()phương pháp này.


Chỉ đối với bản ghi, cả hai phương pháp đều hoạt động đối với tôi trong một ứng dụng bảng điều khiển.
rageit

Tôi xác nhận giải pháp ở trên - Tôi phải gọi log4net.Config.XmlConfigurator.Configure (); trong mã của tôi (sử dụng app.config để log4net hoạt động hiệu quả. Các dòng được in hiệu quả là những dòng sau khi thực thi phương thức Configure ().
luisa rosi

19

Đây là danh sách kiểm tra của tôi khi log4net đang tỏ ra ngoan cố:

  • đảm bảo rằng tệp log4net.config được sao chép vào thư mục bin \ khi xây dựng (đặt thành 'Sao chép nếu mới hơn' trong trình biên dịch)
    • khi xử lý mã đã cài đặt, hãy đảm bảo rằng log4net.config đi kèm với quá trình chạy (được đặt thành 'Nội dung' trong trình biên dịch)
  • đảm bảo rằng người dùng rằng quá trình chạy có quyền ghi vào thư mục nơi các bản ghi sẽ được ghi
  • nếu nghi ngờ, hãy cấp các quyền bừa bãi cho c: \ temp \ và đăng nhập mọi thứ vào đó ()
  • kích hoạt Sysinternal / Dbgview.exe để xem điều đó có cho bạn biết điều gì không

3
"đảm bảo rằng tệp log4net.config được sao chép vào thư mục bin \ khi xây dựng (được đặt thành 'Sao chép nếu mới hơn' trong trình biên dịch)" -> lưu ngày của tôi! Thks rất nhiều!
Hoàng Nguyễn Hữu

8

Để thêm dự án ASP.NET MVC

log4net.Config.XmlConfigurator.Configure();

vào Global.asax.cs cũng giúp:

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        AuthConfig.RegisterAuth();

        log4net.Config.XmlConfigurator.Configure();
    }
}

1
Có một vấn đề rất kỳ lạ với điều này, trong quá trình sản xuất và trên máy tính của sếp tôi, máy ghi nhật ký hoạt động tốt như thế này, nhưng phải đến khi câu trả lời của tôi Kirk thì nó mới hoạt động trên máy tính của tôi. Tôi chỉ nghĩ rằng tôi sẽ cho mọi người biết trong trường hợp họ gặp vấn đề tương tự (dự án MVC btw).
Shelby115

@ Shelby115, cảm ơn rất nhiều! Tôi đang cố gắng đưa các mục nhập log4Net của mình vào ELMAH. Tôi đã có mọi thứ chính xác trong web.config. Tôi đã có 'log4net.Config.XmlConfigurator.Configure ();' trong global.asax.cs của tôi nhưng nó không hoạt động. Đã đến bài đăng SO này và thêm dòng vào assemblyInfo.cs dựa trên Kirk's. Nó vẫn không hoạt động !. Sau khi đọc bình luận của bạn, tôi đã xóa mục trước đó khỏi global.asax.cs và nó bắt đầu hoạt động. Tôi đã dành vài giờ cho việc này và nhận xét của bạn đã giúp ích rất nhiều. Cảm ơn một lần nữa!
user3885927

Mục nhập trong global.asax.cs hoạt động tốt đối với trình đính kèm tệp nhưng không hoạt động tốt đối với trình nối thêm ELMAH. Cách Kirk làm việc cho ELMAH appender (Tôi đặc biệt đã phải gỡ bỏ nó tạo global.asax.cs)
user3885927

Bạn cũng có thể muốn đảm bảo rằng log4net có quyền ghi vào thư mục được định cấu hình cho các tệp nhật ký.
Oladipo Olasemo

@ Shelby115 Dang, phải rất thích khi bạn quên giải pháp và nhận xét của chính bạn giải quyết vấn đề của bạn. Việc đến một trang có câu trả lời đã được bạn ủng hộ cũng là một chỉ báo tốt.
Shelby115

7

Đây là các bước cuối cùng đã ghi nhật ký tệp của tôi hoạt động:

  • -Kiểm tra AssemblyInfo.cs chứa thuộc tính sau. [lắp ráp: log4net.Config.XmlConfigurator] . Điều này tải log4net.
  • Kiểm tra thư mục nhật ký có quyền ghi.
  • Kiểm tra trình ghi có định dạng được chỉ định. Điều này được thực hiện bằng cách kiểm tra mỗi phần tử trong cấu hình của bạn có một phần tử bố cục được chỉ định. Ví dụ:

<appender name="MainLogger"... <layout type="log4net.Layout.SimpleLayout"/>

  • Cuối cùng, hãy thử bật tính năng ghi nhật ký nội bộ log4net để bật tính năng ghi nhật ký bảng điều khiển và kiểm tra bảng điều khiển. Để làm điều này, hãy thêm <add key="log4net.Internal.Debug" value="true"/>vào của bạn appSettings.

<add key = "log4net.Internal.Debug" value = "true" /> Điều này đã giúp tôi khắc phục sự cố. Cảm ơn
Ravi Khambhati.

Quyền của thư mục là những gì đã cho tôi
Omar Himada

6

Tôi đã có kinh nghiệm khi hệ thống ghi nhật ký bị lỗi một cách âm thầm mà không nêu ra các ngoại lệ. Tôi cho rằng điều này có ý nghĩa vì nếu trình ghi nhật ký bị lỗi thì làm thế nào nó có thể ghi lại lỗi không thể thực hiện ghi nhật ký?

Vì vậy, nếu tệp không được tạo trên đĩa, hãy bắt đầu bằng cách xem xét các quyền của hệ thống tệp để đảm bảo người dùng mà ứng dụng của bạn đang chạy có thể ghi tệp mới vào vị trí đĩa đó.

Đối với mục đích thử nghiệm, bạn có thể muốn tạo thủ công tệp trên đĩa cần được ghi vào và mở quyền cho mọi người ghi vào nó. Nếu trình ghi bắt đầu ghi vào nó thì bạn biết nó dựa trên quyền hơn là dựa trên cấu hình.


2

Bên tôi, tôi quên đánh dấu tệp cấu hình sẽ được sao chép trong khi ứng dụng đang được biên dịch.

Sao chép tệp cấu hình vào thư mục đầu ra

Chỉ cần nhấp chuột phải vào tệp log4net.config, chọn thuộc tính và sau đó chọn Sao chép vào Thư mục đầu ra để được Sao chép XXXX


1

Tôi đã thử tất cả những điều trên nhưng không có gì hiệu quả. Thêm dòng này trong phần của app.config configSections đã làm việc cho tôi.

<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net, Version=1.2.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a" />

Đảm bảo rằng VersionPublicKeyTokenchính xác


0
<param name="File" value="mylog.log" />

đang nói "ghi mylog.log vào thư mục thực tế". Điều này có nghĩa là nếu ứng dụng web của bạn thuộc IIS, thì nhật ký sẽ được ghi vào C: \ inetpub \ wwwroot \ appname \ mylog.log.

Nếu tệp nhật ký không có ở đó, thì có thể tài khoản đang chạy ứng dụng không có quyền ghi trên thư mục. Bạn có thể chạy Process Monitor từ SysInternals để xem liệu tệp được ghi ở đâu và ở đâu.

Cũng chạy VS ở chế độ gỡ lỗi, để xem có ngoại lệ nào được ném ra không (Gỡ lỗi-> Ngoại lệ-> Ngoại lệ CLR, kiểm tra Thrown).


0

Trong trường hợp của tôi, tôi quên đặt thuộc tính tệp log4Net.config là "Nội dung" nên tệp không được đưa vào triển khai. Vì vậy, hãy chú ý đến nó:

Compile action : Content

0

Thật không may, không có điều nào ở trên giúp ích. Cấu hình rõ ràng trong lớp được ghi lại một cách phụ thuộc vào các đề xuất cài đặt trước đó đã thực hiện một mẹo nhỏ cho tôi.

string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
log4net.Config.XmlConfigurator.Configure(new FileInfo(assemblyFolder + "/log4net.config"));

-7

Cũng sau vài giờ, tôi đã tìm ra lý do tại sao nó không hoạt động với tôi ...

tôi đã có:

public static class Program
{

    private static CommunicationManager _bcScanner = new CommunicationManager();
    private static ILog _log = LogManager.GetLogger(typeof(Program));
    private static SocketServer socketListener;

nhưng nó phải là:

public static class Program
    {
        private static ILog _log = LogManager.GetLogger(typeof(Program));
        private static CommunicationManager _bcScanner = new CommunicationManager();
        private static SocketServer socketListener;

Vì vậy, hãy đảm bảo rằng ILog nằm ở dòng đầu tiên ....


1
Đây chắc chắn không phải là nguyên nhân. Không quan trọng khi bạn khởi tạo đối tượng ILog miễn là bạn làm điều đó trước khi thực hiện cuộc gọi đến các phương thức ghi nhật ký tức là _log.Info; _log.error, v.v.
Oladipo Olasemo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.