সর্বাধিক দরকারী এনএলওগ কনফিগারেশন [বন্ধ]


348

এনএলগের সাথে লগিংয়ের জন্য সেরা বা সবচেয়ে দরকারী কনফিগারেশনগুলি কী কী? (এগুলি সহজ বা জটিল হতে পারে যতক্ষণ না তারা দরকারী)

আমি একটি নির্দিষ্ট আকারে লগ ফাইলগুলিতে স্বয়ংক্রিয়ভাবে ঘূর্ণিত হওয়া, একটি ব্যতিক্রম আছে কিনা তা লেআউট (লগ বার্তা) পরিবর্তন করা, একবার ত্রুটি দেখা দিলে লগ স্তরকে বাড়িয়ে তোলা ইত্যাদির মতো উদাহরণগুলির কথা ভাবছি etc.

এখানে কয়েকটি লিঙ্ক রয়েছে:


3
এখানে পরীক্ষার উপর ভিত্তি করে কিছু পারফরম্যান্স টিউনিং টিপস রয়েছে: গভীর
নিল

উত্তর:


391

এর মধ্যে কয়েকটি কঠোরভাবে কনফিগারেশন পরামর্শের পরিবর্তে সাধারণ এনএলজি (বা লগিং) টিপসের বিভাগে আসে।

এখানে এখান থেকে কিছু সাধারণ লগিং লিঙ্কগুলি এসও তে রয়েছে (আপনি ইতিমধ্যে এর কিছু বা সমস্ত কিছু আগেই দেখে থাকতে পারেন):

লগ 4 নেট বনাম এনলগ

লগিং সেরা অভ্যাস

একটি লগিং সম্মুখের পয়েন্ট কি?

লগাররা প্রতি ক্লাসে লগার ব্যবহারের পরামর্শ দেয় কেন?

শ্রেণীর উপর ভিত্তি করে আপনার লগার নামকরণের সাধারণ প্যাটার্নটি ব্যবহার করুন Logger logger = LogManager.GetCurrentClassLogger()। এটি আপনাকে আপনার লগারে একটি উচ্চতর ডিগ্রি গ্র্যানুলারিটি দেয় এবং লগারের কনফিগারেশনে আপনাকে দুর্দান্ত স্বাচ্ছন্দ্য দেয় (বিশ্বব্যাপী নিয়ন্ত্রণ করুন, নামফলক দ্বারা, নির্দিষ্ট লগারের নামে ইত্যাদি)।

যেখানে উপযুক্ত সেখানে শ্রেণিবদ্ধ-ভিত্তিক লগার ব্যবহার করুন। হতে পারে আপনার একটি ফাংশন রয়েছে যার জন্য আপনি লগিংকে আলাদাভাবে নিয়ন্ত্রণ করতে চান। হতে পারে আপনার কিছু ক্রস কাটিয়া লগিং উদ্বেগ রয়েছে (পারফরম্যান্স লগিং)।

আপনি যদি ক্লাসের নাম ভিত্তিক লগিং ব্যবহার না করেন তবে আপনার লগারের নামকরণকে কোনও ধরণের শ্রেণিবদ্ধ কাঠামোর (সম্ভবত কার্যকরী অঞ্চল দ্বারা) নামকরণ বিবেচনা করুন যাতে আপনি আপনার কনফিগারেশনে আরও বেশি নমনীয়তা বজায় রাখতে পারেন। উদাহরণস্বরূপ, আপনার কাছে একটি "ডাটাবেস" কার্যকরী অঞ্চল, একটি "বিশ্লেষণ" এফএ এবং একটি "ইউআইআই" এফএ থাকতে পারে। এর প্রত্যেকটির উপ-অঞ্চল থাকতে পারে। সুতরাং, আপনি এই জাতীয় লগরের অনুরোধ করতে পারেন:

Logger logger = LogManager.GetLogger("Database.Connect");
Logger logger = LogManager.GetLogger("Database.Query");
Logger logger = LogManager.GetLogger("Database.SQL");
Logger logger = LogManager.GetLogger("Analysis.Financial");
Logger logger = LogManager.GetLogger("Analysis.Personnel");
Logger logger = LogManager.GetLogger("Analysis.Inventory");

ইত্যাদি। শ্রেণিবদ্ধ লগারের সাহায্যে আপনি বিশ্বব্যাপী লগিং ("*" বা মূল লগার), এফএ (ডেটাবেস, বিশ্লেষণ, ইউআই) দ্বারা বা সুবারিয়া (ডাটাবেস.কনেক্ট, ইত্যাদি) দ্বারা কনফিগার করতে পারেন।

লগারদের অনেকগুলি কনফিগারেশন বিকল্প রয়েছে:

<logger name="Name.Space.Class1" minlevel="Debug" writeTo="f1" /> 
<logger name="Name.Space.Class1" levels="Debug,Error" writeTo="f1" /> 
<logger name="Name.Space.*" writeTo="f3,f4" />
<logger name="Name.Space.*" minlevel="Debug" maxlevel="Error" final="true" /> 

প্রতিটি বিকল্পের অর্থ কী তা বোঝার জন্য আরও তথ্যের জন্য NLog সহায়তা দেখুন । সম্ভবত এখানে সর্বাধিক উল্লেখযোগ্য আইটেমগুলি ওয়াইল্ডকার্ড লগার নিয়ম করার ক্ষমতা, এমন এক ধারণা যে একাধিক লগার নিয়ম একক লগিং বিবৃতিটির জন্য "চালিত" করতে পারে এবং লগার নিয়মটিকে "চূড়ান্ত" হিসাবে চিহ্নিত করা যায় ফলে পরবর্তী নিয়মগুলি কোনওটির জন্য কার্যকর হবে না প্রদত্ত লগিং বিবৃতি।

আপনার আউটপুটে অতিরিক্ত প্রসঙ্গ যুক্ত করতে গ্লোবাল ডায়াগনস্টিক কনটেক্সট, ম্যাপডডায়াগনস্টিক কনটেক্সট এবং নেস্টেডডায়াগনস্টিক কনটেক্সট ব্যবহার করুন।

সরল করার জন্য আপনার কনফিগারেশন ফাইলে "ভেরিয়েবল" ব্যবহার করুন। উদাহরণস্বরূপ, আপনি আপনার বিন্যাসের জন্য ভেরিয়েবলগুলি সংজ্ঞায়িত করতে পারেন এবং তারপরে সরাসরি বিন্যাসটি নির্দিষ্ট করার পরিবর্তে লক্ষ্য কনফিগারেশনে ভেরিয়েবলটি উল্লেখ করতে পারেন।

  <variable name="brief" value="${longdate} | ${level} | ${logger} | ${message}"/>
  <variable name="verbose" value="${longdate} | ${machinename} | ${processid} | ${processname} | ${level} | ${logger} | ${message}"/>
  <targets>
    <target name="file" xsi:type="File" layout="${verbose}" fileName="${basedir}/${shortdate}.log" />
    <target name="console" xsi:type="ColoredConsole" layout="${brief}" />
  </targets>

অথবা, আপনি একটি বিন্যাসে যুক্ত করতে বৈশিষ্ট্যের একটি "কাস্টম" সেট তৈরি করতে পারেন।

  <variable name="mycontext" value="${gdc:item=appname} , ${mdc:item=threadprop}"/>
  <variable name="fmt1withcontext" value="${longdate} | ${level} | ${logger} | [${mycontext}] |${message}"/>
  <variable name="fmt2withcontext" value="${shortdate} | ${level} | ${logger} | [${mycontext}] |${message}"/>

বা, আপনি কনফিগারেশনের মাধ্যমে কঠোরভাবে "দিন" বা "মাস" লেআউট রেন্ডারার তৈরি করার মতো জিনিসগুলি করতে পারেন:

  <variable name="day" value="${date:format=dddd}"/>
  <variable name="month" value="${date:format=MMMM}"/>
  <variable name="fmt" value="${longdate} | ${level} | ${logger} | ${day} | ${month} | ${message}"/>
  <targets>
    <target name="console" xsi:type="ColoredConsole" layout="${fmt}" />
  </targets>

আপনি নিজের ফাইলের নাম সংজ্ঞায়িত করতে লেআউট রেন্ডারগুলিও ব্যবহার করতে পারেন:

  <variable name="day" value="${date:format=dddd}"/>
  <targets>
    <target name="file" xsi:type="File" layout="${verbose}" fileName="${basedir}/${day}.log" />
  </targets>

আপনি যদি প্রতিদিন আপনার ফাইলটি রোল করেন তবে প্রতিটি ফাইলের নাম রাখা যেতে পারে "সোমবার.লগ", "মঙ্গলবার.লগ", ইত্যাদি etc.

আপনার নিজের লেআউট রেন্ডারার লিখতে ভয় পাবেন না। এটি সহজ এবং কনফিগারেশনের মাধ্যমে লগ ফাইলে আপনার নিজস্ব প্রসঙ্গ তথ্য যুক্ত করতে দেয়। উদাহরণস্বরূপ, এখানে একটি লেআউট রেন্ডারার রয়েছে (NLog 1.x ভিত্তিক, 2.0 নয়) যা ট্রেস যোগ করতে পারে or

  [LayoutRenderer("ActivityId")]
  class ActivityIdLayoutRenderer : LayoutRenderer
  {
    int estimatedSize = Guid.Empty.ToString().Length;

    protected override void Append(StringBuilder builder, LogEventInfo logEvent)
    {
      builder.Append(Trace.CorrelationManager.ActivityId);
    }

    protected override int GetEstimatedBufferSize(LogEventInfo logEvent)
    {
      return estimatedSize;
    }
  }

আপনার এনএলজি এক্সটেনশানগুলি (কী সমাবেশ) এটি পছন্দ করে তা এনএলগকে বলুন:

  <extensions>
    <add assembly="MyNLogExtensions"/>
  </extensions>

কাস্টম লেআউট রেন্ডারারটি এর মতো ব্যবহার করুন:

  <variable name="fmt" value="${longdate} | ${ActivityId} | ${message}"/>

অ্যাসিঙ্ক লক্ষ্যগুলি ব্যবহার করুন:

<nlog>
  <targets async="true">
    <!-- all targets in this section will automatically be asynchronous -->
  </targets>
</nlog>

এবং ডিফল্ট লক্ষ্য মোড়ক:

<nlog>  
  <targets>  
    <default-wrapper xsi:type="BufferingWrapper" bufferSize="100"/>  
    <target name="f1" xsi:type="File" fileName="f1.txt"/>  
    <target name="f2" xsi:type="File" fileName="f2.txt"/>  
  </targets>  
  <targets>  
    <default-wrapper xsi:type="AsyncWrapper">  
      <wrapper xsi:type="RetryingWrapper"/>  
    </default-wrapper>  
    <target name="n1" xsi:type="Network" address="tcp://localhost:4001"/>  
    <target name="n2" xsi:type="Network" address="tcp://localhost:4002"/>  
    <target name="n3" xsi:type="Network" address="tcp://localhost:4003"/>  
  </targets>  
</nlog>

যেখানে যথাযথ. সেগুলি সম্পর্কে আরও তথ্যের জন্য এনএলজি ডক্স দেখুন।

কনফিগারেশনটি পরিবর্তন হলে এটি দেখতে NLog কে দেখুন এবং স্বয়ংক্রিয়ভাবে পুনরায় লোড করুন:

<nlog autoReload="true" /> 

এনএলগ সমস্যা সমাধানের জন্য সহায়তা করার জন্য বেশ কয়েকটি কনফিগারেশন বিকল্প রয়েছে

<nlog throwExceptions="true" />
<nlog internalLogFile="file.txt" />
<nlog internalLogLevel="Trace|Debug|Info|Warn|Error|Fatal" />
<nlog internalLogToConsole="false|true" />
<nlog internalLogToConsoleError="false|true" />

আরও তথ্যের জন্য NLog সহায়তা দেখুন।

এনএলজি ২.০ লেআউটআরেন্ডারারের মোড়কে যুক্ত করে যা একটি লেআউট রেন্ডারারের আউটপুট (যেমন ট্রিমিং হোয়াইটস্পেস, বড় হাতের বাচ্চা, লোয়ারকেসিং ইত্যাদি) অতিরিক্ত প্রসেসিংয়ের অনুমতি দেয়।

আপনি যদি লগের উপর নির্ভরশীলতার উপর নির্ভর করে আপনার কোডকে উত্তাপ করতে চান তবে লগারটি মোড়ানোতে ভয় পাবেন না, তবে সঠিকভাবে মোড়ানো। এনএলগের গিথুব সংগ্রহস্থলে কীভাবে মোড়ানো যায় তার উদাহরণ রয়েছে। মোড়ানোর আরেকটি কারণ হতে পারে যে আপনি প্রতিটি লগ করা বার্তায় স্বয়ংক্রিয়ভাবে নির্দিষ্ট প্রসঙ্গের তথ্য যুক্ত করতে চান (এটি LogEventInfo.Context এ রেখে)।

এনএলজি (বা বিষয়টির জন্য অন্য কোনও লগিং ফ্রেমওয়ার্ক) মোড়ানোর পক্ষে (বা বিমূর্ত করা) পক্ষে মতামত রয়েছে। একটু চেষ্টা করে আপনি উভয় পক্ষ উপস্থাপন করে এখানে প্রচুর তথ্য পেতে পারেন।

যদি আপনি মোড়ানো বিবেচনা করে থাকেন, সাধারণ.লগিং ব্যবহার করার বিষয়টি বিবেচনা করুন । এটি বেশ ভালভাবে কাজ করে এবং যদি আপনি এটি করতে ইচ্ছুক হন তবে সহজেই আপনাকে অন্য লগিং ফ্রেমওয়ার্কে স্যুইচ করতে দেয়। এছাড়াও যদি আপনি মোড়ানো বিবেচনা করছেন, আপনি কীভাবে প্রসঙ্গের বিষয়গুলি পরিচালনা করবেন (জিডিসি, এমডিসি, এনডিসি) তা চিন্তা করুন। কমন.লগিং বর্তমানে তাদের বিমূর্ততা সমর্থন করে না, তবে এটি যুক্ত করার ক্ষমতাগুলির কাতারে রয়েছে বলে মনে করা হচ্ছে।


3
দুর্দান্ত উত্তর। কেবল একটি জিনিস যোগ করতে হবে, {{মেশিন} $ {মেশিনেনাম be হওয়া উচিত} Github.com/nlog/NLog/wiki/Layout- রেন্ডার্স দেখুন ।
লিয়াং

2
আমি কমন.লগিংকে কাঁপিয়েছি এবং অনুপস্থিত বিমূর্ততা যোগ করেছি, গিটহাব প্রকল্প বা নিউগেট দেখুন
ড্যানি ভারোড

আমি তাদের নিজস্ব ডকুমেন্টেশনে এনলগ সম্পর্কিত তথ্যমূলক কিছু খুঁজে পেতে ব্যর্থ হয়েছি, সম্ভবত আমি গিথুব উদাহরণগুলি ভুল উপায়ে দেখছি? কে জানে.
JARRRRG

এপিআই (কোনও কনফিগার ফাইল নেই) দিয়ে সেই কাস্টম রেন্ডারার কীভাবে ব্যবহার করবেন? আমি যা অর্জন করতে চাইছি তা এখানে
ইনটেক্সএক্স

ঠিক আছে বুঝেছি. NewLineবিন্যাস কর্ম সঞ্চালিত হয়। আমি যা নিয়ে এসেছি তা এখানে । এটি নিশ্চিত হওয়ার চেয়ে অনেক সহজ যেটি আমি আশা করছিলাম than
ইনটেক্সএক্স

65

ব্যতিক্রমগুলি আলাদাভাবে চিকিত্সা করা

ব্যতিক্রম হলে আমরা প্রায়শই আরও তথ্য পেতে চাই। নিম্নলিখিত কনফিগারেশনের দুটি টার্গেট রয়েছে, একটি ফাইল এবং কনসোল, যা কোনও ব্যতিক্রম তথ্য রয়েছে কিনা তা ফিল্টার করে। (সম্পাদনা: জেরেক ভিএনেক্সটে এটি করার একটি নতুন পদ্ধতি সম্পর্কে পোস্ট করেছেন ।)

কীটি দিয়ে একটি মোড়কের লক্ষ্য রাখতে হবে xsi:type="FilteringWrapper" condition="length('${exception}')>0"

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.mono2.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      autoReload="true"
      internalLogLevel="Warn"
      internalLogFile="nlog log.log"
      >
    <variable name="VerboseLayout" 
              value="${longdate} ${level:upperCase=true} ${message}  
                    (${callsite:includSourcePath=true})"            />
    <variable name="ExceptionVerboseLayout"  
              value="${VerboseLayout} (${stacktrace:topFrames=10})  
                     ${exception:format=ToString}"                  />

    <targets async="true">
        <target name="file" xsi:type="File" fileName="log.log"
                layout="${VerboseLayout}">
        </target>

        <target name="fileAsException"  
                xsi:type="FilteringWrapper" 
                condition="length('${exception}')>0">
            <target xsi:type="File"  
                    fileName="log.log"  
                    layout="${ExceptionVerboseLayout}" />
        </target>

        <target xsi:type="ColoredConsole"
                name="console"
                layout="${NormalLayout}"/>

        <target xsi:type="FilteringWrapper"  
                condition="length('${exception}')>0"  
                name="consoleException">
            <target xsi:type="ColoredConsole" 
                    layout="${ExceptionVerboseLayout}" />
        </target>
    </targets>

    <rules>
        <logger name="*" minlevel="Trace" writeTo="console,consoleException" />
        <logger name="*" minlevel="Warn" writeTo="file,fileAsException" />
    </rules>

</nlog>

1
ব্যতিক্রমটি ফর্ম্যাট করতে পৃথক লক্ষ্য এবং ফিল্টারিংয়ের্পার সহ এটি দুর্দান্ত। আমি সম্প্রতি একটি ছেলের কাছ থেকে একটি প্রশ্নের উত্তর দিয়েছি যা তার আউটপুটে {ব্যতিক্রম} লেআউট রেন্ডারারকে অন্তর্ভুক্ত করতে চেয়েছিল তবে তিনি ব্যতিক্রম না থাকলে স্পষ্টতই লগড (()) পেতে চাননি। এই কৌশলটি সম্ভবত তাঁর পক্ষে ভালভাবে কাজ করবে।
ওয়েজওহে

+1 খুব সুন্দর। আমি এই বুকমার্কটি দীর্ঘকাল ধরে করেছি এবং শর্তসাপেক্ষ লেআউটের ক্ষেত্রে অন্য এসও প্রশ্নের "প্যাট এর মন্তব্য" উল্লেখ করেছি।
eduncan911

1
যদি কোনও ব্যতিক্রম লগ হয় তবে এটি দু'বার লগ ইন (ভার্বোজলআউট অংশ)।
টিয়ান ডো

2
আমি কালই আমার প্রকল্পে এটি চেষ্টা করেছি, যেহেতু আপনি একটি বিধি মিনলেভেল = "সতর্কতা" থেকে "ফাইল, ফাইলএক্সেপশন" তে সেট করেছেন, সমস্ত লগ প্রথমে ফাইল টার্গেটের (কোনও ফিল্টার নয়) লগইন করা হবে, এবং যদি এটি ব্যতিক্রম হয় (দ্বারা ফিল্টার করা হয়) শর্ত) এটি ফাইলআসেক্সেপশনে লগডও হবে।
টিয়েন ডু

3
@ তিয়ানডিক ওহ, আমি দেখছি এটি বোধগম্য, যদিও ব্যতিক্রম নিজেই (সম্পূর্ণ বিবরণে) কেবল একবার লগইন হবে (তবে এর বার্তাটি দু'বার লগ হবে)। আপনি সম্ভবত এটি যুক্ত করে condition="length('${exception}')=0(বা সম্ভবত এটি ==) এটি ঠিক করতে পারেন target name="file"
প্যাট

60

স্পষ্টতই, আপনি এখন উইন্ডোজের জন্য গ্রোল সহ এনএলজি ব্যবহার করতে পারেন ।

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <extensions>
        <add assembly="NLog.Targets.GrowlNotify" />
    </extensions>

    <targets>
        <target name="growl" type="GrowlNotify" password="" host="" port="" />
    </targets>

    <rules>
        <logger name="*" minLevel="Trace" appendTo="growl"/>
    </rules>

</nlog>

উইন্ডোজের জন্য গ্রোল সহ এনএলগ উইন্ডোজের জন্য গ্রোলের সাথে এনএলগ ট্রেস বার্তা উইন্ডোজের জন্য গ্রোলের সাথে এনএলগ ডিবাগ বার্তা উইন্ডোজের জন্য গ্রোলের সাথে এনএলজি তথ্য বার্তা উইন্ডোজের জন্য গ্রোলের সাথে এনএলজি সতর্কতা বার্তা উইন্ডোজের জন্য গ্রোলের সাথে এনএলগ ত্রুটি বার্তা উইন্ডোজের জন্য গ্রোলের সাথে এনএলজি মারাত্মক বার্তা


আপনি কি আমাকে বলতে পারবেন রিমোর্ট সংযোগের জন্য কী করতে হবে? জিনিসটি লোকালহোস্টের জন্য আমার পক্ষে কাজ করে তবে আমি হোস্টে কিছু আইপি ঠিকানা দিলে এটি কাজ করে না !!
নীল

@ নীল, আপনার লক্ষ্য কম্পিউটারে গ্রাউলে "সুরক্ষা" সেটিংস পরীক্ষা করা উচিত। আপনাকে স্পষ্টভাবে "ল্যান" বিজ্ঞপ্তিগুলি সক্ষম করতে হবে এবং আপনি একটি পাসওয়ার্ড সেটআপ করতে চাইতে পারেন (যা আপনাকে পরে আপনার এনএলওগ টার্গেটে যুক্ত করতে হবে)। তবে আমি পছন্দ করি না যে দূরবর্তী বিজ্ঞপ্তিগুলি গ্রোলে "লোকাল মেশিন" এর "উত্স" সহ শো-আপ করেছে; বিজ্ঞপ্তিগুলির সূত্রপাত কোথায় তা জানতে আমাকে হোস্টটি লগ এন্ট্রিগুলিতে যুক্ত করতে হবে।
কেনি এভিট

আমি আমার স্থানীয় মেশিনে কাজ করার জন্য বিজ্ঞপ্তিগুলি পেতে পারি, তবে দূর থেকে নয়। আমার সুরক্ষা সেটিংসে গ্রোলে কোনও পাসওয়ার্ড নেই, তাই আমি যুক্ত করা সমস্ত আইপি এবং পোর্ট। কিন্তু কিছুই পাঠানো হয় না।
জ্যাক রিলি

1
এই প্রকল্পটি মারা গেছে 100%
বিকাশকারী

28

এক্সএমএল এর মাধ্যমে এনএলগ কনফিগার করুন তবে প্রোগ্রামিয়ালি

কি? আপনি কি জানতেন যে এনএলএগ এটি কনফিগার ফাইল থেকে পড়ার বিপরীতে আপনি সরাসরি আপনার অ্যাপ্লিকেশন থেকে এনএলগ এক্সএমএল নির্দিষ্ট করতে পারেন? ভাল, আপনি পারেন। ধরা যাক যে আপনার বিতরণকৃত অ্যাপ্লিকেশন রয়েছে এবং আপনি সর্বত্র একই কনফিগারেশনটি ব্যবহার করতে চান। আপনি প্রতিটি স্থানে একটি কনফিগার ফাইল রাখতে পারেন এবং এটি আলাদাভাবে বজায় রাখতে পারবেন, আপনি একটি কেন্দ্রীয় অবস্থানে একটি রক্ষণাবেক্ষণ করতে এবং এটি উপগ্রহের অবস্থানগুলিতে ঠেলে দিতে পারেন বা আপনি সম্ভবত আরও অনেক কিছু করতে পারেন। অথবা, আপনি আপনার এক্সএমএল একটি ডেটাবেজে সংরক্ষণ করতে পারবেন, এটি অ্যাপ্লিকেশন শুরুতে পেতে এবং এনএলগকে সরাসরি সেই এক্সএমএল দিয়ে কনফিগার করতে পারেন (সম্ভবত এটি পর্যায়ক্রমে ফিরে এসেছে কিনা তা পরীক্ষা করে দেখুন কিনা)।

  string xml = @"<nlog>
                   <targets>
                     <target name='console' type='Console' layout='${message}' />
                   </targets>

                   <rules>
                     <logger name='*' minlevel='Error' writeTo='console' />
                   </rules>
                 </nlog>";

  StringReader sr = new StringReader(xml);
  XmlReader xr = XmlReader.Create(sr);
  XmlLoggingConfiguration config = new XmlLoggingConfiguration(xr, null);
  LogManager.Configuration = config;
  //NLog is now configured just as if the XML above had been in NLog.config or app.config

  logger.Trace("Hello - Trace"); //Won't log
  logger.Debug("Hello - Debug"); //Won't log
  logger.Info("Hello - Info");   //Won't log
  logger.Warn("Hello - Warn");   //Won't log
  logger.Error("Hello - Error"); //Will log
  logger.Fatal("Hello - Fatal"); //Will log

  //Now let's change the config (the root logging level) ...
  string xml2 = @"<nlog>
                  <targets>
                     <target name='console' type='Console' layout='${message}' />
                   </targets>

                   <rules>
                     <logger name='*' minlevel='Trace' writeTo='console' />
                   </rules>
                 </nlog>";

  StringReader sr2 = new StringReader(xml2);
  XmlReader xr2 = XmlReader.Create(sr2);
  XmlLoggingConfiguration config2 = new XmlLoggingConfiguration(xr2, null);
  LogManager.Configuration = config2;

  logger.Trace("Hello - Trace"); //Will log
  logger.Debug("Hello - Debug"); //Will log
  logger.Info("Hello - Info");   //Will log
  logger.Warn("Hello - Warn");   //Will log
  logger.Error("Hello - Error"); //Will log
  logger.Fatal("Hello - Fatal"); //Will log

এটি কতটা দৃ is় তা আমি নিশ্চিত নই, তবে এই উদাহরণটি এমন লোকদের জন্য একটি দরকারী প্রারম্ভিক বিন্দু সরবরাহ করে যা সম্ভবত এটির মতো কনফিগার করার চেষ্টা করতে চায়।


এটি খুব ভালভাবে কাজ করে ... এটি ব্যবহার না করে লগিং সিস্টেমটিকে গতিশীলভাবে পুনরায় কনফিগার করা সম্ভব নয়। এটি বিশেষত তাই যদি আপনি বাইরের কোনও ফাইলের সাথে লিঙ্ক করেন (অন্তর্ভুক্ত)
নিউটোপিয়ান

2
এটি কাজ করেছে, যদিও আমাকে অন্তর্ভুক্ত করে "ভাল" এক্সএমএল লিখতে হয়েছিল:<?xml version='1.0' encoding='utf-8' ?><nlog xmlns='http://nlog-project.org/schemas/NLog.xsd' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
গ্যাডি

1
এটি কেন্দ্রীয়ীকরণের কনফিগারেশনের একটি দুর্দান্ত সেগওয়ে। ভবিষ্যতের পাঠকগণ, এই নমুনায় হার্ড কোডড এক্সএমএল কেবলমাত্র ডেমো (আইএমএইচও) এর জন্য, এটি একটি ডাটাবেস বা সেন্ট্রালাইজড ফাইল থেকে পড়া বাস্তব বাস্তবায়ন হতে পারে।
গ্রানাডা কোডার

@ ওয়েজওহে; কেন আমি ত্রুটি পাই (লকারের অস্তিত্ব নেই)? আমি কেবল কোডটি অনুলিপি করে আটকান
Bsflasher

22

কোনও ত্রুটি আছে কি না তার উপর নির্ভর করে বিভিন্ন স্তরে লগিং করা

আপনার কোডটিতে ত্রুটি থাকলে এই উদাহরণটি আপনাকে আরও তথ্য পাওয়ার অনুমতি দেয়। মূলত, এটি বার্তাগুলিকে বাফার করে এবং নির্দিষ্ট শর্ত পূরণ না করা হলে (যেমন সতর্কতা অবলম্বন করে) কেবলমাত্র আউটপুট করে (যেমন একটি ত্রুটি হয়েছে, সুতরাং লগ স্তরটি = = ত্রুটি), তবে এটি আরও তথ্য আউটপুট দেবে (যেমন লগ স্তরগুলি থেকে সমস্ত বার্তা> = ট্রেস)। বার্তাগুলি বাফার হওয়ার কারণে এটি আপনাকে ত্রুটি বা ত্রুটি-ধারণাটি লগ হওয়ার আগে কী হয়েছিল সে সম্পর্কে ট্রেস তথ্য সংগ্রহ করতে দেয় - খুব দরকারী!

আমি উত্স কোডের একটি উদাহরণ থেকে এটিকে মানিয়ে নিয়েছি । আমাকে প্রথমে ছুঁড়ে ফেলা হয়েছিল কারণ আমি ছাড়লামAspNetBufferingWrapper (যেহেতু আমার কোনও এএসপি অ্যাপ নয়) - এটি দেখা গেছে যে পোস্ট ফিল্টারিংআর্পারকে কিছু বাফার টার্গেট প্রয়োজন। নোট করুন যে target-refউপরোক্ত-সংযুক্ত উদাহরণে ব্যবহৃত উপাদানগুলি এনএলগ ০.০ এ ব্যবহার করা যাবে না (আমি। নেট 4.0 অ্যাপের জন্য 1.0 রিফ্রেশ ব্যবহার করছি); আপনার লক্ষ্যটি র‍্যাপার ব্লকের ভিতরে রাখা দরকার। এছাড়াও লক্ষ করুন যে লজিক সিনট্যাক্স (অর্থাত্ प्रतीকের চেয়ে বৃহত্তর বা কম-এর চেয়ে কম, <এবং>) চিহ্নগুলি ব্যবহার করতে হবে, এক্সএমএল সেই চিহ্নগুলির জন্য পালাতে পারে না (যেমন &gt;এবং &lt;) বা অন্যথায় এনএলগ ত্রুটি করবে।

app.config:

<?xml version="1.0"?>
<configuration>
    <configSections>
        <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
    </configSections>

    <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          throwExceptions="true" internalLogToConsole="true" internalLogLevel="Warn" internalLogFile="nlog.log">
        <variable name="appTitle" value="My app"/>
        <variable name="csvPath" value="${specialfolder:folder=Desktop:file=${appTitle} log.csv}"/>

        <targets async="true">
            <!--The following will keep the default number of log messages in a buffer and write out certain levels if there is an error and other levels if there is not. Messages that appeared before the error (in code) will be included, since they are buffered.-->
            <wrapper-target xsi:type="BufferingWrapper" name="smartLog">
                <wrapper-target xsi:type="PostFilteringWrapper">
                    <!--<target-ref name="fileAsCsv"/>-->
                    <target xsi:type="File" fileName="${csvPath}"
                    archiveAboveSize="4194304" concurrentWrites="false" maxArchiveFiles="1" archiveNumbering="Sequence"
                    >
                        <layout xsi:type="CsvLayout" delimiter="Tab" withHeader="false">
                            <column name="time" layout="${longdate}" />
                            <column name="level" layout="${level:upperCase=true}"/>
                            <column name="message" layout="${message}" />
                            <column name="callsite" layout="${callsite:includeSourcePath=true}" />
                            <column name="stacktrace" layout="${stacktrace:topFrames=10}" />
                            <column name="exception" layout="${exception:format=ToString}"/>
                            <!--<column name="logger" layout="${logger}"/>-->
                        </layout>
                    </target>

                     <!--during normal execution only log certain messages--> 
                    <defaultFilter>level >= LogLevel.Warn</defaultFilter>

                     <!--if there is at least one error, log everything from trace level--> 
                    <when exists="level >= LogLevel.Error" filter="level >= LogLevel.Trace" />
                </wrapper-target>
            </wrapper-target>

        </targets>

        <rules>
            <logger name="*" minlevel="Trace" writeTo="smartLog"/>
        </rules>
    </nlog>
</configuration>

এনএলগের কয়েকটি সংস্করণে (মনো এবং আমার মনে হয় ২.০), এটি স্ট্যাকওভারফ্লো এক্সেক্সশন সৃষ্টি করে, তবে অন্যগুলিতে নয় (এনএলজি 1 রিফ্রেশ)।
প্যাট

ওভারফ্লো সম্পর্কে - এটি কেবলমাত্র CSV ধরণের লেআউটের কারণে বলে মনে হচ্ছে - যদি আমি নিয়মিত বিন্যাস করি তবে কোনও সমস্যা নেই।
প্যাট

ফাইলএএসসিএসভি টার্গেট-রেফ কী, সেখানে? আমি এই উদাহরণটি NLog v2.0.0.2000 এর বিরুদ্ধে কাজ করার চেষ্টা করছি তবে এখন পর্যন্ত ব্যর্থ।
পিটার মাউসন

@ পিটারমাউশন fileAsCsvটার্গেট-রেফ আমার পরীক্ষা থেকে কেবল একটি নিদর্শন। আমি বিশ্বাস করি যে এনএলওগ 2 এর সিএসভিএলআউটগুলির সাথে সমস্যা ছিল / যা এনএলগ 1 / রিফ্রেশের নেই।
প্যাট

22

আমি এই প্রশ্নের বেশ কয়েকটি যুক্তিসঙ্গত আকর্ষণীয় উত্তর সরবরাহ করেছি:

এনলগ - একটি লগ ফাইলের জন্য শিরোনাম বিভাগ উত্পাদন করা

শিরোনাম যুক্ত করা হচ্ছে:

প্রশ্নটি লগ ফাইলটিতে একটি শিরোনাম কীভাবে যুক্ত করবেন তা জানতে চেয়েছিলেন। এই জাতীয় কনফিগার এন্ট্রি ব্যবহার করে আপনাকে বাকী লগ এন্ট্রিগুলির বিন্যাস থেকে আলাদাভাবে শিরোনামের বিন্যাসটি সংজ্ঞায়িত করতে দেয়। অ্যাপ্লিকেশনটির শুরুতে একটি বার্তা লগ করতে সম্ভবত একটি শিরোনামে লগার ব্যবহার করুন, সম্ভবত আপনার শিরোনাম পান:

শিরোনাম এবং ফাইল লেআউট সংজ্ঞা দিন:

  <variable name="HeaderLayout" value="This is the header.  Start time = ${longdate} Machine = ${machinename} Product version = ${gdc:item=version}"/>
  <variable name="FileLayout" value="${longdate} | ${logger} | ${level} | ${message}" />

লেআউটগুলি ব্যবহার করে লক্ষ্যগুলি নির্ধারণ করুন:

<target name="fileHeader" xsi:type="File" fileName="xxx.log" layout="${HeaderLayout}" />
<target name="file" xsi:type="File" fileName="xxx.log" layout="${InfoLayout}" />

লগারগুলি সংজ্ঞায়িত করুন:

<rules>
  <logger name="headerlogger" minlevel="Trace" writeTo="fileHeader" final="true" />
  <logger name="*" minlevel="Trace" writeTo="file" />
</rules>

সম্ভবত শুরুর দিকে শিরোনামটি লিখুন:

  GlobalDiagnosticsContext.Set("version", "01.00.00.25");

  LogManager.GetLogger("headerlogger").Info("It doesn't matter what this is because the header format does not include the message, although it could");

এটি মূলত "ব্যতিক্রমগুলি আলাদাভাবে আচরণ করা" ধারণাটির অন্য একটি সংস্করণ।

প্রতিটি লগ স্তরকে একটি ভিন্ন বিন্যাস সহ লগ করুন

একইভাবে, পোস্টারটি লগিং স্তরের প্রতি ফর্ম্যাট কীভাবে পরিবর্তন করতে হয় তা জানতে চেয়েছিল। শেষ লক্ষ্যটি কী ছিল তা আমার কাছে পরিষ্কার ছিল না (এবং এটি "আরও ভাল" উপায়ে অর্জন করা যায় কিনা) তবে আমি একটি কনফিগারেশন প্রদান করতে সক্ষম হয়েছিল যা তিনি যা বলেছিলেন তা করেছে:

  <variable name="TraceLayout" value="This is a TRACE - ${longdate} | ${logger} | ${level} | ${message}"/> 
  <variable name="DebugLayout" value="This is a DEBUG - ${longdate} | ${logger} | ${level} | ${message}"/> 
  <variable name="InfoLayout" value="This is an INFO - ${longdate} | ${logger} | ${level} | ${message}"/> 
  <variable name="WarnLayout" value="This is a WARN - ${longdate} | ${logger} | ${level} | ${message}"/> 
  <variable name="ErrorLayout" value="This is an ERROR - ${longdate} | ${logger} | ${level} | ${message}"/> 
  <variable name="FatalLayout" value="This is a FATAL - ${longdate} | ${logger} | ${level} | ${message}"/> 
  <targets> 
    <target name="fileAsTrace" xsi:type="FilteringWrapper" condition="level==LogLevel.Trace"> 
      <target xsi:type="File" fileName="xxx.log" layout="${TraceLayout}" /> 
    </target> 
    <target name="fileAsDebug" xsi:type="FilteringWrapper" condition="level==LogLevel.Debug"> 
      <target xsi:type="File" fileName="xxx.log" layout="${DebugLayout}" /> 
    </target> 
    <target name="fileAsInfo" xsi:type="FilteringWrapper" condition="level==LogLevel.Info"> 
      <target xsi:type="File" fileName="xxx.log" layout="${InfoLayout}" /> 
    </target> 
    <target name="fileAsWarn" xsi:type="FilteringWrapper" condition="level==LogLevel.Warn"> 
      <target xsi:type="File" fileName="xxx.log" layout="${WarnLayout}" /> 
    </target> 
    <target name="fileAsError" xsi:type="FilteringWrapper" condition="level==LogLevel.Error"> 
      <target xsi:type="File" fileName="xxx.log" layout="${ErrorLayout}" /> 
    </target> 
    <target name="fileAsFatal" xsi:type="FilteringWrapper" condition="level==LogLevel.Fatal"> 
      <target xsi:type="File" fileName="xxx.log" layout="${FatalLayout}" /> 
    </target> 
  </targets> 


    <rules> 
      <logger name="*" minlevel="Trace" writeTo="fileAsTrace,fileAsDebug,fileAsInfo,fileAsWarn,fileAsError,fileAsFatal" /> 
      <logger name="*" minlevel="Info" writeTo="dbg" /> 
    </rules> 

আবার, ব্যতিক্রমগুলি আলাদাভাবে চিকিত্সার সাথে খুব মিল ।


1
শান্ত! GlobalDiagnosticsContextআগে দেখিনি ।
প্যাট

10

টুইটারে লগ করুন

একটি লগ 4 নেট টুইটার অ্যাপেন্ডার সম্পর্কে এই পোস্টের উপর ভিত্তি করে, আমি ভেবেছিলাম NLog টুইটার টার্গেট লেখার জন্য আমি আমার হাতটি চেষ্টা করব (২.০ নয়, এনএলওগ ১.০ রিফ্রেশ ব্যবহার করে)। হায়, এ পর্যন্ত আমি আসলে সফলভাবে পোস্ট করার জন্য একটি টুইট পেতে সক্ষম হইনি। আমি জানি না যে এটি আমার কোড, টুইটার, আমাদের সংস্থার ইন্টারনেট সংযোগ / ফায়ারওয়াল, বা কীতে কিছু ভুল if কেউ যদি চেষ্টা করে দেখতে আগ্রহী হয় আমি কোডটি এখানে পোস্ট করছি। নোট করুন যে তিনটি পৃথক "পোস্ট" পদ্ধতি আছে। আমি যে প্রথম চেষ্টা করেছি তা হ'ল পোস্টমেসেজটোটোরিয়র। পোস্টমেসেজটিও টুইটার মূলত অরিগনাল পোস্টে পোস্টলগিংইভেন্টের সমান। যদি আমি এটি ব্যবহার করি তবে আমি 401 টি ব্যতিক্রম পাই। পোস্টমেসেজব্যাসিক একই ব্যতিক্রম পায়। পোস্টমেসেজ কোনও ত্রুটি ছাড়াই চলে, তবে বার্তাটি এটি এখনও টুইটারে তৈরি করে না। পোস্টমেসেজ এবং পোস্টম্যাসেজ বেসিক উদাহরণগুলির ভিত্তিতে যা আমি এখানে এসওতে পেয়েছি।

এফওয়াইআই - আমি এখনই এই পোস্টের একটি উত্তরের জন্য @ জেসন ডিলারের একটি মন্তব্য পেয়েছি যাতে বলা হয়েছে যে টুইটারটি "পরের মাসে" বেসিক প্রমাণীকরণটি বন্ধ করে দিতে চলেছে। এটি ২০১০ সালের মে মাসে ফিরে এসেছিল এবং এটি এখন ২০১০ সালের ডিসেম্বর, সুতরাং আমি অনুমান করি যে এটি কেন কাজ করছে না।

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Web;
using System.IO;

using NLog;
using NLog.Targets;
using NLog.Config;

namespace NLogExtensions
{
  [Target("TwitterTarget")]
  public class TwitterTarget : TargetWithLayout
  {
    private const string REQUEST_CONTENT_TYPE = "application/x-www-form-urlencoded";  

    private const string REQUEST_METHOD = "POST";  

    // The source attribute has been removed from the Twitter API,  
    // unless you're using OAuth.  
    // Even if you are using OAuth, there's still an approval process.  
    // Not worth it; "API" will work for now!  
    // private const string TWITTER_SOURCE_NAME = "Log4Net";  
    private const string TWITTER_UPDATE_URL_FORMAT = "http://twitter.com/statuses/update.xml?status={0}";  

    [RequiredParameter]
    public string TwitterUserName { get; set; }

    [RequiredParameter]
    public string TwitterPassword { get; set; }

    protected override void Write(LogEventInfo logEvent)
    {
      if (string.IsNullOrWhiteSpace(TwitterUserName) || string.IsNullOrWhiteSpace(TwitterPassword)) return;

      string msg = this.CompiledLayout.GetFormattedMessage(logEvent);

      if (string.IsNullOrWhiteSpace(msg)) return;

      try
      {
        //PostMessageToTwitter(msg);
        PostMessageBasic(msg);
      }
      catch (Exception ex)
      {
        //Should probably do something here ...
      }
    }

    private void PostMessageBasic(string msg)
    {
      // Create a webclient with the twitter account credentials, which will be used to set the HTTP header for basic authentication 
      WebClient client = new WebClient { Credentials = new NetworkCredential { UserName = TwitterUserName, Password = TwitterPassword } };

      // Don't wait to receive a 100 Continue HTTP response from the server before sending out the message body 
      ServicePointManager.Expect100Continue = false;

      // Construct the message body 
      byte[] messageBody = Encoding.ASCII.GetBytes("status=" + msg);

      // Send the HTTP headers and message body (a.k.a. Post the data) 
      client.UploadData(@"http://twitter.com/statuses/update.xml", messageBody);
    }

    private void PostMessage(string msg)
    {
      string user = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(TwitterUserName + ":" + TwitterPassword));
      byte [] bytes = System.Text.Encoding.UTF8.GetBytes("status=" + msg.ToTweet());
      HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://twitter.com/statuses/update.xml");
      request.Method = "POST";
      request.ServicePoint.Expect100Continue = false;
      request.Headers.Add("Authorization", "Basic " + user);
      request.ContentType = "application/x-www-form-urlencoded";
      request.ContentLength = bytes.Length;
      Stream reqStream = request.GetRequestStream();
      reqStream.Write(bytes, 0, bytes.Length);
      reqStream.Close();
    }

    private void PostMessageToTwitter(string msg)
    {
      var updateRequest = HttpWebRequest.Create(string.Format(TWITTER_UPDATE_URL_FORMAT,
                                                HttpUtility.UrlEncode(msg.ToTweet()))) as HttpWebRequest;
      updateRequest.ContentLength = 0;
      updateRequest.ContentType = REQUEST_CONTENT_TYPE;
      updateRequest.Credentials = new NetworkCredential(TwitterUserName, TwitterPassword);
      updateRequest.Method = REQUEST_METHOD;

      updateRequest.ServicePoint.Expect100Continue = false;

      var updateResponse = updateRequest.GetResponse() as HttpWebResponse;

      if (updateResponse.StatusCode != HttpStatusCode.OK && updateResponse.StatusCode != HttpStatusCode.Continue)
      {
        throw new Exception(string.Format("An error occurred while invoking the Twitter REST API [Response Code: {0}]", updateResponse.StatusCode));
      }
    }
  }

  public static class Extensions
  {
    public static string ToTweet(this string s)
    {
      if (string.IsNullOrEmpty(s) || s.Length < 140)
      {
        return s;
      }

      return s.Substring(0, 137) + "...";
    }
  }
}

এটির মতো কনফিগার করুন:

এনএলগকে লক্ষ্যযুক্ত সমাবেশটি বলুন:

<extensions>
  <add assembly="NLogExtensions"/>
</extensions>

লক্ষ্যটি কনফিগার করুন:

<targets>
    <target name="twitter" type="TwitterTarget" TwitterUserName="yourtwittername" TwitterPassword="yourtwitterpassword" layout="${longdate} ${logger} ${level} ${message}" />
</targets>

যদি কেউ এটি চেষ্টা করে এবং সাফল্য পান তবে আপনার অনুসন্ধানগুলি সহ পোস্ট করুন।


টুইটার OAuth ব্যবহার করে - .NET-
প্যাট

7

একটি বাহ্যিক ওয়েবসাইট / ডাটাবেস প্রতিবেদন করা

আমি আমাদের অ্যাপ্লিকেশনগুলি থেকে কেবল এবং স্বয়ংক্রিয়ভাবে ত্রুটিগুলি রিপোর্ট করার একটি উপায় চেয়েছিলাম (যেহেতু ব্যবহারকারীরা প্রায়শই না করে)। আমি যে সহজ সমাধানটি নিয়ে আসতে পারি তা হ'ল একটি পাবলিক ইউআরএল - একটি ওয়েব পৃষ্ঠা যা ইনপুট নিতে পারে এবং এটি একটি ডেটাবেজে সংরক্ষণ করতে পারে - যা কোনও অ্যাপ্লিকেশন ত্রুটিতে ডেটা প্রেরণ করা হয়। (ডাটাবেসটি কোনও ত্রুটি আছে কিনা তা জানতে কোনও দেব বা স্ক্রিপ্ট দ্বারা পরীক্ষা করা যেতে পারে))

আমি পিএইচপিতে ওয়েব পৃষ্ঠাটি লিখেছি এবং ডেটা সঞ্চয় করার জন্য একটি মাইএসকিএল ডাটাবেস, ব্যবহারকারী এবং টেবিল তৈরি করেছি। আমি চারটি ব্যবহারকারীর ভেরিয়েবল, একটি আইডি এবং একটি টাইমস্ট্যাম্পের সিদ্ধান্ত নিয়েছি। সম্ভাব্য ভেরিয়েবলগুলি (হয় ইউআরএলে অন্তর্ভুক্ত হয় বা পোষ্ট ডেটা হিসাবে অন্তর্ভুক্ত থাকে):

  • app (আবেদনের নাম)
  • msg (বার্তা - যেমন ব্যতিক্রম ঘটেছে ...)
  • dev (বিকাশকারী - যেমন প্যাট)
  • src(উত্স - এটি মেশিনের উপর নির্ভরশীল কোনও ভেরিয়েবল থেকে আসে যার উপর অ্যাপ্লিকেশনটি চলছিল, যেমন Environment.MachineNameবা এরকম কিছু)
  • log (একটি লগ ফাইল বা ভার্বোজ বার্তা)

(সমস্ত ভেরিয়েবল alচ্ছিক, তবে সেগুলির কোনওটি সেট না করা থাকলে কিছুই জানানো হয় না - সুতরাং আপনি যদি কেবল ওয়েবসাইট ইউআরএল যান তবে ডিবিতে কিছুই প্রেরণ করা হয় না।)

ইউআরএলটিতে ডেটা প্রেরণ করতে, আমি এনএলগের WebServiceলক্ষ্য ব্যবহার করেছি । (দ্রষ্টব্য, প্রথমে এই টার্গেটটি নিয়ে আমার কয়েকটি সমস্যা হয়েছিল until আমি উত্সটির দিকে না তাকানো আগেই আমি বুঝতে পারি urlনি যে আমার সাথে কোনও শেষ হতে পারে না /))

সর্বোপরি বাহ্যিক অ্যাপ্লিকেশনগুলিতে ট্যাব রাখার জন্য এটি কোনও খারাপ সিস্টেম নয়। (অবশ্যই, নম্র কাজটি হ'ল আপনার ব্যবহারকারীদের অবহিত করা যে আপনি সম্ভবত সংবেদনশীল ডেটা প্রতিবেদন করবেন এবং তাদের বেছে নেওয়ার / আউটপুটে যাওয়ার উপায় প্রদান করবেন))

মাইএসকিউএল স্টাফ

(ডিবি ব্যবহারকারীর নিজস্ব ডেটাবেজে INSERTএই টেবিলটিতে কেবল বিশেষাধিকার রয়েছে ))

CREATE TABLE `reports` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `ts` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
  `applicationName` text,
  `message` text,
  `developer` text,
  `source` text,
  `logData` longtext,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='storage place for reports from external applications'

ওয়েবসাইট কোড

(পিএইচপি 5.3 বা 5.2 সঙ্গে PDO সক্রিয় , ফাইল index.phpমধ্যে /reportফোল্ডার)

<?php
$app = $_REQUEST['app'];
$msg = $_REQUEST['msg'];
$dev = $_REQUEST['dev'];
$src = $_REQUEST['src'];
$log = $_REQUEST['log'];

$dbData =
    array(  ':app' => $app,
            ':msg' => $msg,
            ':dev' => $dev,
            ':src' => $src,
            ':log' => $log
    );
//print_r($dbData); // For debugging only! This could allow XSS attacks.
if(isEmpty($dbData)) die("No data provided");

try {
$db = new PDO("mysql:host=$host;dbname=reporting", "reporter", $pass, array(
    PDO::ATTR_PERSISTENT => true
));
$s = $db->prepare("INSERT INTO reporting.reports 
    (
    applicationName, 
    message, 
    developer, 
    source, 
    logData
    )
    VALUES
    (
    :app, 
    :msg, 
    :dev, 
    :src, 
    :log
    );"
    );
$s->execute($dbData);
print "Added report to database";
} catch (PDOException $e) {
// Sensitive information can be displayed if this exception isn't handled
//print "Error!: " . $e->getMessage() . "<br/>";
die("PDO error");
}

function isEmpty($array = array()) {
    foreach ($array as $element) {
        if (!empty($element)) {
            return false;
        }
    }
    return true;
}
?>

অ্যাপ কোড (NLog কনফিগারেশন ফাইল)

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      throwExceptions="true" internalLogToConsole="true" internalLogLevel="Warn" internalLogFile="nlog.log">
    <variable name="appTitle" value="My External App"/>
    <variable name="csvPath" value="${specialfolder:folder=Desktop:file=${appTitle} log.csv}"/>
    <variable name="developer" value="Pat"/>

    <targets async="true">
        <!--The following will keep the default number of log messages in a buffer and write out certain levels if there is an error and other levels if there is not. Messages that appeared before the error (in code) will be included, since they are buffered.-->
        <wrapper-target xsi:type="BufferingWrapper" name="smartLog">
            <wrapper-target xsi:type="PostFilteringWrapper">
                <target xsi:type="File" fileName="${csvPath}"
                archiveAboveSize="4194304" concurrentWrites="false" maxArchiveFiles="1" archiveNumbering="Sequence"
                >
                    <layout xsi:type="CsvLayout" delimiter="Comma" withHeader="false">
                        <column name="time" layout="${longdate}" />
                        <column name="level" layout="${level:upperCase=true}"/>
                        <column name="message" layout="${message}" />
                        <column name="callsite" layout="${callsite:includeSourcePath=true}" />
                        <column name="stacktrace" layout="${stacktrace:topFrames=10}" />
                        <column name="exception" layout="${exception:format=ToString}"/>
                        <!--<column name="logger" layout="${logger}"/>-->
                    </layout>
                </target>

                 <!--during normal execution only log certain messages--> 
                <defaultFilter>level >= LogLevel.Warn</defaultFilter>

                 <!--if there is at least one error, log everything from trace level--> 
                <when exists="level >= LogLevel.Error" filter="level >= LogLevel.Trace" />
            </wrapper-target>
        </wrapper-target>

        <target xsi:type="WebService" name="web"
                url="http://example.com/report" 
                methodName=""
                namespace=""
                protocol="HttpPost"
                >
            <parameter name="app" layout="${appTitle}"/>
            <parameter name="msg" layout="${message}"/>
            <parameter name="dev" layout="${developer}"/>
            <parameter name="src" layout="${environment:variable=UserName} (${windows-identity}) on ${machinename} running os ${environment:variable=OSVersion} with CLR v${environment:variable=Version}"/>
            <parameter name="log" layout="${file-contents:fileName=${csvPath}}"/>
        </target>

    </targets>

    <rules>
        <logger name="*" minlevel="Trace" writeTo="smartLog"/>
        <logger name="*" minlevel="Error" writeTo="web"/>
    </rules>
</nlog>

দ্রষ্টব্য: লগ ফাইলের আকার নিয়ে কিছু সমস্যা থাকতে পারে তবে আমি এটি কেটে ফেলার কোনও সহজ উপায় খুঁজে পাইনি (যেমন একটি লা * নিক্সের tailআদেশ )।


এটি একটি প্রকল্পের জন্য কাজ করেছে, তবে অন্যদের মধ্যে আমার কাছে সমস্যা রয়েছে url: ইনারএক্সেপশন: সিস্টেম.আইনডাওলিকাস্টেক্স এক্সপেনশন বার্তা = 'সিস্টেম.স্ট্রিং' থেকে 'সিস্টেম.উরি' তে অবৈধ কাস্ট। উত্স = mscorlib স্ট্যাকট্র্যাস: System.Convers.DefaultToType (আইসনভারটিবল মান, টাইপ টার্গেটটাইপ, আইফরম্যাটপ্রভাইডার সরবরাহকারী) System.String.System.IConvertible.ToType (টাইপ টাইপ, আইফর্ম্যাটপ্রভাইডার সরবরাহকারী) System.Convers.ChangeType রূপান্তর টাইপ টাইপ, , আইফোর্ম্যাটপ্রাইডার সরবরাহকারী)
প্যাট

আপনি যদি লগটি নিরীক্ষণ করতে সক্ষম হন এবং কোনও ত্রুটির ঘটনায় অবহিত হন তবে অন্য একটি বিকল্পটি একটি টুইটার টার্গেট হতে পারে। টুইটার Appender জন্য লিখিত জন্য এই লিঙ্কটি দেখুন log4net: twitterappender.codeplex.com মূল ব্লগ পোস্ট এই আলোচনা এখানে: caseywatson.com/2009/07/07/log4net-twitter-awesome এটা কিছু লিখতে জন্য অনুরূপ প্রশংসনীয় সহজ হওয়া উচিত NLog।
ওয়েজওহে

আমি এনএলওগ টুইটারটারেট লিখে প্রায় বোকা হয়েছি কিন্তু আসলে টুইট পোস্ট করে সাফল্য পাইনি। আমি উত্তর হিসাবে কোড পোস্ট করেছি। আপনি যদি চান তা নিখরচায় চেষ্টা করুন।
wageoghe

6

শর্তসাপেক্ষ লেআউটগুলি ব্যবহার করে প্রতিটি লগ স্তরকে আলাদা বিন্যাসের সাথে লগ করার সহজ উপায়

<variable name="VerboseLayout" value="${level:uppercase=true}: ${longdate} | ${logger}    : 
${when:when=level == LogLevel.Trace:inner=MONITOR_TRACE ${message}} 
${when:when=level == LogLevel.Debug:inner=MONITOR_DEBUG ${message}} 
${when:when=level == LogLevel.Info:inner=MONITOR_INFO ${message}} 
${when:when=level == LogLevel.Warn:inner=MONITOR_WARN ${message}} 
${when:when=level == LogLevel.Error:inner=MONITOR_ERROR ${message}} 
${when:when=level == LogLevel.Fatal:inner=MONITOR_CRITICAL ${message}} |     
${exception:format=tostring} | ${newline} ${newline}" />

দেখুন https://github.com/NLog/NLog/wiki/When-Filter সিনট্যাক্স জন্য


4

সিলভারলাইট থেকে লগ করুন

সিলভারলাইটের সাথে এনএলগ ব্যবহার করার সময় আপনি সরবরাহিত ওয়েব পরিষেবাদির মাধ্যমে ট্রেসটি সার্ভার সাইডে প্রেরণ করতে পারেন । বিচ্ছিন্ন স্টোরেজটিতে আপনি একটি স্থানীয় ফাইলেও লিখতে পারেন যা ওয়েব সার্ভারটি উপলভ্য না থাকলে কার্যকর হয়। বিশদগুলির জন্য এখানে দেখুন , যেমন নিজেকে লক্ষ্য হিসাবে গড়ে তুলতে এরকম কিছু ব্যবহার করুন:

namespace NLogTargets
{
    [Target("IsolatedStorageTarget")]
    public sealed class IsolatedStorageTarget : TargetWithLayout
    {
        IsolatedStorageFile _storageFile = null;
        string _fileName = "Nlog.log"; // Default. Configurable through the 'filename' attribute in nlog.config

        public IsolatedStorageTarget()
        {
        }

        ~IsolatedStorageTarget()
        {
            if (_storageFile != null)
            {
                _storageFile.Dispose();
                _storageFile = null;
            }
        }

        public string filename
        {
            set
            {
                _fileName = value; 
            }
            get
            {
                return _fileName;  
            }
         }

        protected override void Write(LogEventInfo logEvent)
        {
            try
            {
                writeToIsolatedStorage(this.Layout.Render(logEvent));
            }
            catch (Exception e)
            {
                // Not much to do about his....
            }
        }

        public void writeToIsolatedStorage(string msg)
        {
            if (_storageFile == null)
                _storageFile = IsolatedStorageFile.GetUserStoreForApplication();
            using (IsolatedStorageFile isolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                // The isolated storage is limited in size. So, when approaching the limit
                // simply purge the log file. (Yeah yeah, the file should be circular, I know...)
                if (_storageFile.AvailableFreeSpace < msg.Length * 100)
                {
                    using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(_fileName, FileMode.Truncate, FileAccess.Write, isolatedStorage))
                    { }
                }
                // Write to isolated storage
                using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(_fileName, FileMode.Append, FileAccess.Write, isolatedStorage))
                {
                    using (TextWriter writer = new StreamWriter(stream))
                    {
                        writer.WriteLine(msg);
                    }
                }
            }
        }
    } 
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.