2.1 প্রথম লগার - log4j

আপনি ইতিমধ্যেই জানেন, লগের ইতিহাস System.err.println()কনসোলে একটি রেকর্ডের আউটপুট দিয়ে শুরু হয়েছিল। এটি এখনও সক্রিয়ভাবে ডিবাগিংয়ের জন্য ব্যবহৃত হয়, উদাহরণস্বরূপ, Intellij IDEA কনসোলে ত্রুটি বার্তা প্রদর্শন করতে এটি ব্যবহার করে। কিন্তু এই বিকল্পের কোনো সেটিংস নেই, তাই চলুন এগিয়ে যান।

প্রথম এবং সবচেয়ে জনপ্রিয় লগার বলা হয়েছিল Log4j। এটি একটি ভাল এবং অত্যন্ত কাস্টমাইজযোগ্য সমাধান ছিল। বিভিন্ন পরিস্থিতিতে, এই সিদ্ধান্তটি কখনই জেডিকেতে আসেনি, যা সমগ্র সম্প্রদায়কে ব্যাপকভাবে বিচলিত করেছিল।

এই লগারটি শুধু লগই করতে সক্ষম ছিল না, এটি প্রোগ্রামারদের জন্য প্রোগ্রামারদের দ্বারা তৈরি করা হয়েছিল এবং লগিংয়ের সাথে ক্রমাগত উদ্ভূত সমস্যাগুলি সমাধান করার অনুমতি দেয়।

আপনি ইতিমধ্যে জানেন যে, লগগুলি শেষ পর্যন্ত লেখা হয় যাতে কিছু ব্যক্তি সেগুলি পড়ে এবং প্রোগ্রামটির অপারেশন চলাকালীন কী ঘটেছিল তা বোঝার চেষ্টা করে - কী এবং কখন প্রত্যাশিত ভুল হয়েছিল।

এর জন্য তিনটি জিনিস ছিল log4j:

  • সাবপ্যাকেজ লগিং;
  • পরিশিষ্টের সেট (ফলাফল);
  • গরম পুনরায় লোড সেটিংস।

প্রথমত, সেটিংস log4jএমনভাবে লেখা যেতে পারে যাতে একটি প্যাকেজে লগিং সক্ষম করা যায় এবং অন্য প্যাকেজে এটি নিষ্ক্রিয় করা যায়। উদাহরণস্বরূপ, লগ ইন সক্ষম করা সম্ভব ছিল com.codegym.server, কিন্তু এটি অক্ষম করুন com.codegym.server.payment৷ এটি লগ থেকে অপ্রয়োজনীয় তথ্য দ্রুত অপসারণ করা সম্ভব করেছে।

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

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

এবং অবশেষে, তৃতীয়ত, log4jএটি পুনরায় চালু না করেই প্রোগ্রামটি চলাকালীন লগ সেটিংস সরাসরি পরিবর্তন করার অনুমতি দেয়। একটি নির্দিষ্ট ত্রুটির অতিরিক্ত তথ্য খোঁজার জন্য লগগুলির কাজ সংশোধন করার প্রয়োজন হলে এটি খুব সহজ ছিল৷

গুরুত্বপূর্ণ ! লগের দুটি সংস্করণ রয়েছে log4j: 1.2.x এবং 2.xx , যেগুলি একে অপরের সাথে বেমানান

আপনি কোড ব্যবহার করে প্রকল্পে লগার সংযোগ করতে পারেন:

<dependencies>
  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.2</version>
  </dependency>

  <dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.2</version>
  </dependency>
</dependencies>

2.2 প্রথম অফিসিয়াল লগার - JUL: java.util.logging

জাভা সম্প্রদায়ে লগারদের চিড়িয়াখানা উপস্থিত হওয়ার পরে, বিকাশকারীরা JDKএকটি স্ট্যান্ডার্ড লগার তৈরি করার সিদ্ধান্ত নিয়েছে যা সবাই ব্যবহার করবে। লগারটি এভাবেই হাজির JUL: প্যাকেজ java.util.logging

যাইহোক, এর বিকাশের সময়, লগারের নির্মাতারা একটি ভিত্তি হিসাবে গ্রহণ করেছিলেন না log4j, বরং আইবিএম থেকে লগারের একটি রূপ, যা এর বিকাশকে প্রভাবিত করেছিল। ভাল খবর হল লগার JULঅন্তর্ভুক্ত করা হয়েছে JDK, খারাপ খবর হল খুব কম লোকই এটি ব্যবহার করে৷

জুল

ডেভেলপাররা শুধুমাত্র "অন্য সার্বজনীন মান"JUL তৈরি করেনি , তারা এর জন্য তাদের নিজস্ব লগিং স্তরও তৈরি করেছিল, যা সেই সময়ে জনপ্রিয় লগারদের দ্বারা গৃহীত হওয়া থেকে ভিন্ন ছিল৷

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

যদিও লগার নিজেই বেশ ভালো। লগার তৈরি করা কমবেশি একই। এটি করার জন্য, আপনাকে আমদানি করতে হবে:


java.util.logging.Logger log = java.util.logging.Logger.getLogger(LoggingJul.class.getName());

লগিং কোথা থেকে আসছে তা জানার জন্য ক্লাসের নাম বিশেষভাবে পাস করা হয়।

শুধুমাত্র প্রকাশের সাথে, বিকাশকারীরা গুরুত্বপূর্ণ সমস্যাগুলি সমাধান করেছে, যার পরে এটি JULব্যবহার করা সত্যিই সুবিধাজনক। তার আগে, এটি একরকম দ্বিতীয়-দর লগার ছিল।

এই লগার ল্যাম্বডা এক্সপ্রেশন এবং অলস মূল্যায়ন সমর্থন করে। দিয়ে শুরু করে Java 8, আপনি পাস করতে পারেন Supplier<String>। এটি শুধুমাত্র সেই মুহুর্তে একটি স্ট্রিং পড়তে এবং তৈরি করতে সাহায্য করে যখন এটি সত্যিই প্রয়োজন হয় এবং প্রতিবার নয়, যেমনটি আগে ছিল।

একটি যুক্তি সহ পদ্ধতি Supplier<String> msgSupplierএই মত দেখায়:

public void info(Supplier msgSupplier) {
   log(Level.INFO, msgSupplier);
}

2.3 প্রথম লগার র্যাপার - JCL: জাকার্তা কমন্স লগিং

দীর্ঘদিন ধরে লগারদের মধ্যে কোনো একক মান ছিল না, এটি JULএকটি হওয়া উচিত ছিল, কিন্তু এটি আরও খারাপ ছিল log4j, তাই একটি একক মান কখনও দেখা যায়নি৷ কিন্তু লগারদের একটি সম্পূর্ণ চিড়িয়াখানা হাজির, যার প্রত্যেকটি একই হতে চেয়েছিল।

জেসিএল

যাইহোক, সাধারণ জাভা বিকাশকারীরা পছন্দ করেননি যে প্রায় প্রতিটি লাইব্রেরির নিজস্ব লগার রয়েছে এবং একটি বিশেষ উপায়ে কোনওভাবে কনফিগার করা প্রয়োজন। অতএব, সম্প্রদায় অন্যান্য লগারদের উপর একটি বিশেষ মোড়ক তৈরি করার সিদ্ধান্ত নিয়েছে - এইভাবেJCL: jakarta commons logging

এবং আবার, যে প্রকল্পটি নেতা হওয়ার জন্য তৈরি করা হয়েছিল, তা হয়ে ওঠেনি। আপনি একজন বিজয়ী তৈরি করতে পারবেন না, আপনি শুধুমাত্র একজন বিজয়ী হতে পারেন। কার্যকারিতা JCLখুব খারাপ ছিল এবং কেউ এটি ব্যবহার করতে চায়নি। লগার, সমস্ত লগার প্রতিস্থাপন করার জন্য ডিজাইন করা হয়েছে, একই ভাগ্য পূরণ করেছে কারণ এটি JULব্যবহার করা হয়নি।

যদিও এটি অ্যাপাচি সম্প্রদায়ের দ্বারা প্রকাশিত অনেক লাইব্রেরিতে যুক্ত করা হয়েছে, তবে লগারদের চিড়িয়াখানা কেবল বেড়েছে।

2.4 প্রথম শেষ লগার - লগব্যাক

কিন্তু এখানেই শেষ নয়. বিকাশকারী log4jসিদ্ধান্ত নিয়েছে যে তিনিই সবচেয়ে বুদ্ধিমান (আচ্ছা, বেশিরভাগ লোকই তার লগার ব্যবহার করেছে) এবং একটি নতুন উন্নত লগার লেখার সিদ্ধান্ত নিয়েছে যা log4jঅন্যান্য লগারদের সুবিধাগুলিকে একত্রিত করবে।

নতুন লগারকে ডাকা হলো Logback। এই লগারটিই ভবিষ্যতের একক লগার হওয়ার কথা ছিল যা সবাই ব্যবহার করবে। এটি একই ধারণার উপর ভিত্তি করে ছিল log4j

আপনি কোড ব্যবহার করে এই লগারটিকে প্রকল্পের সাথে সংযুক্ত করতে পারেন:

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.6</version>
</dependency>

পার্থক্য ছিল Logback:

  • উন্নত কর্মক্ষমতা;
  • স্থানীয় সমর্থন যোগ করা হয়েছে slf4j;
  • প্রসারিত ফিল্টারিং বিকল্প।

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

ডিফল্টরূপে, Logbackএটির কোনো সেটিংসের প্রয়োজন হয় না এবং স্তর DEBUGএবং উপরের সমস্ত লগ রেকর্ড করে। আপনার যদি ভিন্ন আচরণের প্রয়োজন হয় তবে এটি কনফিগারেশনের মাধ্যমে কনফিগার করা যেতে পারে xml:

<configuration>
    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>app.log</file>
        <encoder>
            <pattern>%d{HH:mm:ss,SSS} %-5p [%c] - %m%n</pattern>
        </encoder>
    </appender>
    <logger name="org.hibernate.SQL" level="DEBUG" />
    <logger name="org.hibernate.type.descriptor.sql" level="TRACE" />
    <root level="info">
        <appender-ref ref="FILE" />
    </root>
</configuration>

2.5 সর্বশেষ সার্বজনীন লগার - SLF4J: জাভার জন্য সহজ লগিং ফ্যাকেড

সোনালী গড় খুঁজে পেতে কতক্ষণ হতে পারে...

2006 সালে, একজন নির্মাতা log4jপ্রকল্পটি ছেড়ে দিয়েছিলেন এবং একটি সর্বজনীন লগার তৈরি করার জন্য আবার চেষ্টা করার সিদ্ধান্ত নিয়েছিলেন। কিন্তু এই সময় এটি একটি নতুন লগার ছিল না, কিন্তু একটি নতুন সার্বজনীন মান (র্যাপার) যা বিভিন্ন লগারকে একসাথে যোগাযোগ করতে দেয়।

এই লগারকে বলা হতো slf4j — Simple Logging Facade for Java, এটার চারপাশে একটা মোড়ক ছিল log4j,, JULcommon-loggins and logbackএই লগারটি একটি বাস্তব সমস্যার সমাধান করেছে - লগারদের একটি চিড়িয়াখানা পরিচালনা করা, তাই সবাই অবিলম্বে এটি ব্যবহার করা শুরু করে৷

আমরা বীরত্বের সাথে নিজেদের জন্য তৈরি করা সমস্যার সমাধান করি। আপনি দেখতে পাচ্ছেন, অগ্রগতি এমন পর্যায়ে পৌঁছেছে যে আমরা মোড়কের উপর একটি মোড়ক তৈরি করেছি ...

মোড়ানো নিজেই দুটি অংশ নিয়ে গঠিত:

  • API, যা অ্যাপ্লিকেশনগুলিতে ব্যবহৃত হয়;
  • প্রতিটি লগারের জন্য পৃথক নির্ভরতা হিসাবে যোগ করা হয় যে বাস্তবায়ন.

আপনি কোড ব্যবহার করে প্রকল্পে লগার সংযোগ করতে পারেন:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.2</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.17.2</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>2.17.2</version>
</dependency>

সঠিক বাস্তবায়ন সংযোগ করার জন্য এটি যথেষ্ট এবং এটিই: পুরো প্রকল্পটি এটির সাথে কাজ করবে।

2.6 slf4j-এ অপ্টিমাইজেশান

Slf4jলগিং এর জন্য স্ট্রিং ফরম্যাটিং এর মত সব নতুন বৈশিষ্ট্য সমর্থন করে । এর আগেও এমন সমস্যা ছিল। ধরা যাক আপনি লগে একটি বার্তা প্রিন্ট করতে চান:

log.debug("User " + user + " connected from " + request.getRemoteAddr());

এই কোডের সাথে একটি সমস্যা আছে. ধরুন আপনার অ্যাপ্লিকেশনটি কাজ করে productionএবং লগে কোনো লিখছে না DEBUG-messages, তবে, পদ্ধতিটি log.debug()এখনও কল করা হবে, এবং যখন এটি কল করা হবে, নিম্নলিখিত পদ্ধতিগুলিও বলা হবে:

  • user.toString();
  • request.getRemoteAddr();

এই পদ্ধতিগুলি কল করলে অ্যাপ্লিকেশনটি ধীর হয়ে যায়। তাদের কল শুধুমাত্র ডিবাগিং এর সময় প্রয়োজন, কিন্তু যেভাবেই হোক তাদের কল করা হয়।

যুক্তির দৃষ্টিকোণ থেকে, এই সমস্যাটি লগিং লাইব্রেরিতেই সমাধান করতে হয়েছিল। এবং log4j এর প্রথম সংস্করণে সমাধানটি এসেছে:

if (log.isDebugEnabled()) {
    log.debug("User " + user + " connected from " + request.getRemoteAddr());
}

লগের জন্য এক লাইনের বদলে এখন তিনটা লেখা দরকার ছিল। যা নাটকীয়ভাবে কোডের পঠনযোগ্যতাকে খারাপ করেছে এবং এর জনপ্রিয়তা কমিয়ে দিয়েছে log4j

লগার slf4jস্মার্ট লগিং অফার করে পরিস্থিতির কিছুটা উন্নতি করতে সক্ষম হয়েছিল। এটি এই মত লাগছিল:

log.debug("User {} connected from {}", user, request.getRemoteAddr());

যেখানে {}পদ্ধতিতে পাস করা আর্গুমেন্টের সন্নিবেশ বোঝায়। অর্থাৎ, প্রথমটি {}ব্যবহারকারীর সাথে, {}দ্বিতীয়টি request.getRemoteAddr().

লগিং লেভেল লগিং করার অনুমতি দিলেই এই পরামিতিগুলিকে একটি একক বার্তায় সংযুক্ত করা হবে। নিখুঁত নয়, তবে অন্যান্য সমস্ত বিকল্পের চেয়ে ভাল।

এর পরে, SLF4Jএটি জনপ্রিয়তায় দ্রুত বাড়তে শুরু করে, এই মুহুর্তে এটি সর্বোত্তম সমাধান।

অতএব, আমরা একটি বান্ডিলের উদাহরণ ব্যবহার করে লগিং বিবেচনা করব slf4j-log4j12