আমার জীবনে প্রথমবারের মতো আমি নিজেকে এমন অবস্থানে দেখতে পেলাম যেখানে আমি একটি জাভা এপিআই লিখছি যা খোলা উত্সাহিত হবে। আশা করি আরও অনেক প্রকল্পের অন্তর্ভুক্ত হবে।
লগিংয়ের জন্য আমি (এবং প্রকৃতপক্ষে আমি যাদের সাথে কাজ করি) সর্বদা JUL (java.util.logging) ব্যবহার করেছি এবং এর সাথে কখনও কোনও সমস্যা হয়নি। তবে এখন আমার এপিআই বিকাশের জন্য আমার কী করা উচিত তা আরও বিশদে বুঝতে হবে। আমি এ নিয়ে কিছু গবেষণা করেছি এবং যে তথ্য পেয়েছি সেগুলি নিয়ে আমি আরও বিভ্রান্ত হয়ে পড়েছি। অতএব এই পোস্ট।
যেহেতু আমি জুলু থেকে এসেছি আমি সে বিষয়ে পক্ষপাতদুষ্ট। বাকিটা সম্পর্কে আমার জ্ঞান এত বড় নয়।
আমি যে গবেষণাটি করেছি তা থেকেই আমি এই কারণগুলি নিয়ে এসেছি কেন লোকেরা JUL পছন্দ করে না:
"আমি জাভা উন্নয়নশীল অনেক আগে সূর্যের জুলাই মুক্তি শুরু এটা শুধু আমার বদলে লগিং-কাঠামোর-এক্স চালিয়ে যাওয়ার জন্য নতুন কিছু শিখতে সহজ ছিল" । হুম। আমি মজা করছি না, এটি আসলে লোকেরা বলে। এই যুক্তি দিয়ে আমরা সবাই কোবল করতে পারি। (তবে আমি অবশ্যই এটি একটি অলস বন্ধু হিসাবে নিজেকে সম্পর্কিত করতে পারি)
"আমি জুলেতে লগিং স্তরের নাম পছন্দ করি না" । ঠিক আছে, গুরুত্ব সহকারে, এটি একটি নতুন নির্ভরতা প্রবর্তনের কারণ হিসাবে যথেষ্ট নয়।
"আমি জুল থেকে আউটপুট মানক বিন্যাস পছন্দ করি না" । হুম। এটি কেবল কনফিগারেশন। আপনাকে কোড-ভিত্তিক কিছু করতে হবে না। (সত্য, পুরানো দিনগুলি ফিরে আসার জন্য আপনার নিজের ফর্ম্যাটর ক্লাসটি তৈরি করতে হতে পারে)।
"আমি অন্যান্য লাইব্রেরি ব্যবহার করি যা লগিং-ফ্রেমওয়ার্ক-এক্সও ব্যবহার করে তাই আমি কেবল এটি ব্যবহার করা সহজ বলে মনে করি" । এটি একটি বিজ্ঞপ্তি যুক্তি, তাই না? 'প্রত্যেকে' কেন লগিং-ফ্রেমওয়ার্ক-এক্স ব্যবহার করে এবং জুল নয়?
"অন্য প্রত্যেকে লগিং-ফ্রেমওয়ার্ক-এক্স ব্যবহার করছে" । এটি আমার কাছে উপরের একটি বিশেষ কেস। সংখ্যাগরিষ্ঠতা সবসময় সঠিক হয় না।
তাহলে আসল বড় প্রশ্নটি হল কেন জুল নয়? । আমি কী মিস করেছি? লগিং ফেসডেস (এসএলএফ 4 জে, জেসিএল) এর জন্য রেইসন ডি'ট্রে হ'ল একাধিক লগিং বাস্তবায়ন historতিহাসিকভাবেই বিদ্যমান ছিল এবং এর কারণটি সত্যিই জেএলএল এর আগে ফিরে এসেছিল যেহেতু আমি এটি দেখছি। JUL যদি নিখুঁত হয় তবে লগিং ফ্যাসিডের অস্তিত্ব থাকবে না, বা কী? বিষয়গুলিকে আরও বিভ্রান্তিকর করে তোলার জন্য কিছুটা হলেও হ'ল হ্যান্ডলার, ফর্ম্যাটর এবং এমনকি লগ ম্যানেজারটি অদলবদল করার অনুমতি দেয় এটি একটি মুখোমুখি।
একই জিনিস (লগিং) করার একাধিক উপায়ে আলিঙ্গন করার পরিবর্তে আমাদের প্রশ্ন করা উচিত নয় যে এগুলি প্রথম স্থানে কেন প্রয়োজনীয় ছিল? (এবং দেখুন যে কারণগুলি এখনও বিদ্যমান কিনা)
ঠিক আছে, আমার গবেষণাটি এখনও অবধি বেশ কয়েকটি জিনিস নিয়ে গেছে যা আমি দেখতে পাচ্ছি জুলের সাথে আসল সমস্যা হতে পারে :
পারফরম্যান্স । কেউ কেউ বলেন যে এসএলএফ 4 জে পারফরম্যান্স বাকীগুলির চেয়ে সেরা। এটি আমার কাছে অকালীন অপ্টিমাইজেশনের একটি মামলা বলে মনে হচ্ছে। যদি আপনাকে প্রতি সেকেন্ডে কয়েকশ মেগাবাইট লগ করতে হয় তবে আমি নিশ্চিত নই যে আপনি যেভাবেই সঠিক পথে আছেন। জুল ইউএলও বিকশিত হয়েছে এবং জাভা ১.৪ এ আপনি যে পরীক্ষা করেছেন তা আর সত্য হতে পারে না। আপনি এটি সম্পর্কে এখানে পড়তে পারেন এবং এই ফিক্সটি এটি জাভা into-এ পরিণত করেছে Many তবে টেমপ্লেট ভিত্তিক লগিং এই ব্যয়টিকে এড়িয়ে চলে এবং এটি জুলিয়ায়ও বিদ্যমান। ব্যক্তিগতভাবে আমি কখনই টেমপ্লেট ভিত্তিক লগিং লিখি না। তার জন্য খুব অলস। উদাহরণস্বরূপ আমি যদি এটি JUL এর সাথে করি:
log.finest("Lookup request from username=" + username + ", valueX=" + valueX + ", valueY=" + valueY));
আমার আইডিই আমাকে সতর্ক করবে এবং অনুমতি চাইবে যে এটিতে এটি পরিবর্তন করা উচিত:
log.log(Level.FINEST, "Lookup request from username={0}, valueX={1}, valueY={2}", new Object[]{username, valueX, valueY});
.. যা আমি অবশ্যই গ্রহণ করব। অনুমতি দেওয়া ! আপনার সাহায্যের জন্য ধন্যবাদ।
সুতরাং আমি আসলে এই জাতীয় বিবৃতি নিজেই লিখি না, এটি আইডিই দ্বারা সম্পন্ন হয়।
পারফরম্যান্সের ইস্যুতে উপসংহারে আমি এমন কিছু পাইনি যা সুপারিশ করবে যে প্রতিযোগিতার তুলনায় জুলের পারফরম্যান্স ঠিক নয়।
ক্লাসপথ থেকে কনফিগারেশন । বাক্সের বাইরে জুল ইউএস ক্লাসপথ থেকে কোনও কনফিগারেশন ফাইল লোড করতে পারে না। এটি করার জন্য এটি কয়েকটি লাইনের কোড । আমি দেখতে পাচ্ছি কেন এটি বিরক্তিকর হতে পারে তবে সমাধানটি সংক্ষিপ্ত এবং সহজ।
আউটপুট হ্যান্ডলারের উপলব্ধতা । জুলুল বাক্সের বাইরে 5 আউটপুট হ্যান্ডলারগুলি নিয়ে আসে: কনসোল, ফাইল স্ট্রিম, সকেট এবং মেমরি। এগুলি প্রসারিত বা নতুন লেখা যেতে পারে। এটি উদাহরণস্বরূপ ইউএনআইএক্স / লিনাক্স সিসলগ এবং উইন্ডোজ ইভেন্ট লগকে লেখা হতে পারে। আমার ব্যক্তিগতভাবে কখনও এই প্রয়োজনীয়তা ছিল না বা আমি এটি ব্যবহার করতে দেখিনি তবে কেন এটি কার্যকর বৈশিষ্ট্য হতে পারে তার সাথে আমি অবশ্যই সম্পর্কিত হতে পারি। লগব্যাক উদাহরণস্বরূপ সিসলগের জন্য একটি অ্যাপেন্ডারের সাথে আসে। তবুও আমি তর্ক করব
- আউটপুট গন্তব্যগুলির জন্য 99.5% প্রয়োজনের বাক্সটি জুল-আউট-অফ-বক্সের দ্বারা আবৃত।
- বিশেষ প্রয়োজনগুলি অন্য কোনও কিছুর শীর্ষে না রেখে JUL এর শীর্ষে কাস্টম হ্যান্ডলারের দ্বারা সরবরাহ করা যেতে পারে। আমার কাছে এমন কিছুই নেই যা প্রস্তাব দেয় যে অন্য লগিং ফ্রেমওয়ার্কের তুলনায় জুলুলের জন্য সিসলগ আউটপুট হ্যান্ডলারটি লিখতে আরও বেশি সময় লাগে।
আমি সত্যিই উদ্বিগ্ন যে আমি কিছু উপেক্ষা করেছি। JUL ব্যতীত লগিং facades এবং লগিং বাস্তবায়নের ব্যবহার এত ব্যাপক যে আমাকে এই সিদ্ধান্তে পৌঁছাতে হবে যে কেবল আমি বুঝতে পারি না। এই প্রথম হবে না, আমি ভয় করি। :-)
তাহলে আমার এপিআই দিয়ে আমার কী করা উচিত? আমি এটি সফল হতে চান। আমি অবশ্যই "প্রবাহের সাথে যেতে পারি" এবং এসএলএফ 4 জে (যা আজকাল সর্বাধিক জনপ্রিয় বলে মনে হচ্ছে) বাস্তবায়ন করতে পারি তবে নিজের স্বার্থের জন্য আমাকে এখনও বুঝতে হবে আজকের জুলের কী ভুল আছে যা সমস্ত ফাজকে ওয়্যারেন্ট করে? আমি কি আমার লাইব্রেরির জন্য জুলিয়াল বেছে নিয়ে নাশকতা করব?
পারফরম্যান্স পরীক্ষার
(07-জুলাই -২০২২ এ নোলান 00০০ দ্বারা বিভাগ যুক্ত করা হয়েছে)
এসএলএফ 4 জে'র প্যারামিট্রাইজেশন জুলের তুলনায় 10 গুণ বা আরও বেশি দ্রুতগতির বিষয়ে নীচে সেকির একটি উল্লেখ রয়েছে। তাই আমি কিছু সাধারণ পরীক্ষা করা শুরু করেছি। প্রথম নজরে দাবিটি অবশ্যই সঠিক। এখানে প্রাথমিক ফলাফল (তবে পড়ুন!):
- কার্যকর করার সময় এসএলএফ 4 জে, ব্যাকএন্ড লগব্যাক: 1515
- কার্যকর করার সময় এসএলএফ 4 জে, ব্যাকএন্ড জুল: 12938
- ফাঁসির সময় জুল: 16911
উপরের সংখ্যাগুলি এমসেকস তাই কম ভাল। সুতরাং 10 গুণ পারফরম্যান্স পার্থক্য প্রথম আসলে বেশ কাছাকাছি হয়। আমার প্রাথমিক প্রতিক্রিয়া: এটি অনেক!
এখানে পরীক্ষার মূল বিষয়। যেমন একটি পূর্ণসংখ্যা দেখা যায় এবং একটি লুপে একটি স্ট্রিং তৈরি করা হয় যা লগ স্টেটমেন্টে ব্যবহৃত হয়:
for (int i = 0; i < noOfExecutions; i++) {
for (char x=32; x<88; x++) {
String someString = Character.toString(x);
// here we log
}
}
(আমি লগ স্টেটমেন্টটিতে আদিম উপাত্ত টাইপ (এই ক্ষেত্রে কোনও ইনট) এবং আরও জটিল ডেটা টাইপ (এক্ষেত্রে একটি স্ট্রিং) রাখতে চেয়েছিলাম wanted এটি নিশ্চিত নয় তবে এটি আপনার কাছে রয়েছে))
এসএলএফ 4 জে লগের বিবৃতি:
logger.info("Logging {} and {} ", i, someString);
জুলুলের জন্য লগ স্টেটমেন্ট:
logger.log(Level.INFO, "Logging {0} and {1}", new Object[]{i, someString});
প্রকৃত পরিমাপ হওয়ার আগে একবার পরীক্ষা করা একই পরীক্ষা দিয়ে জেভিএম 'ওয়ার্ম আপ' হয়েছিল। জাভা 1.7.03 উইন্ডোজ 7. এ ব্যবহৃত হয়েছিল এসএলএফ 4 জে (v1.6.6) এবং লগব্যাক (v1.0.6) এর সর্বশেষ সংস্করণ ব্যবহার করা হয়েছিল। স্টডআউট এবং স্ট্ডার নাল ডিভাইসে পুনঃনির্দেশিত হয়েছিল।
তবে, এখনই সাবধান, এটি সক্রিয় করে যে জুল তার বেশিরভাগ সময় ব্যয় করছে getSourceClassName()
কারণ ডিফল্টভাবে জুল আউটপুটে উত্স শ্রেণীর নাম মুদ্রণ করে, যখন লগব্যাক না। সুতরাং আমরা আপেল এবং কমলা তুলনা করছি। আমাকে আবার পরীক্ষা করতে হবে এবং লগিং বাস্তবায়নগুলি একই পদ্ধতিতে কনফিগার করতে হবে যাতে তারা আসলে একই জিনিস আউটপুট দেয়। তবে আমি সন্দেহ করি যে এসএলএফ 4 জে + লগব্যাক এখনও শীর্ষে আসবে তবে উপরে বর্ণিত প্রাথমিক সংখ্যাগুলি থেকে অনেক দূরে। সাথে থাকুন.
বিটিডব্লিউ: আমি প্রথমবারের মতো এসএলএফ 4 জে বা লগব্যাকের সাথে কাজ করেছি The একটি মনোরম অভিজ্ঞতা। আপনি যখন শুরু করছেন তখন অবশ্যই জুল ইউএসএল অবশ্যই অনেক কম স্বাগত।
পরীক্ষার পারফরম্যান্স (অংশ 2)
(08-JUL-2012-এ nolan600 দ্বারা বিভাগ যুক্ত করা হয়েছে)
যেহেতু এটি দেখা যাচ্ছে যে আপনি জেআুলএলগুলিতে কীভাবে আপনার প্যাটার্নটি কনফিগার করেন তা কার্য সম্পাদনের জন্য গুরুত্বপূর্ণ নয়, অর্থাত্ এতে উত্সের নাম অন্তর্ভুক্ত রয়েছে কি না। আমি খুব সাধারণ প্যাটার্ন দিয়ে চেষ্টা করেছি:
java.util.logging.SimpleFormatter.format="%4$s: %5$s [%1$tc]%n"
এবং এটি উপরের সময়গুলিতে মোটেও পরিবর্তন করে নি। আমার প্রোফাইলার প্রকাশ করেছেন যে লগার এখনও কলগুলিতে প্রচুর সময় ব্যয় করেছিল getSourceClassName()
এমনকি এটি আমার প্যাটার্নের অংশ না হলেও। প্যাটার্নটি কোনও বিষয় নয়।
অতএব আমি পারফরম্যান্সের ইস্যুতে শেষ করছি যে কমপক্ষে পরীক্ষিত টেম্পলেট ভিত্তিক লগ স্টেটমেন্টের জন্য মোটামুটি 10 টির একটি ফ্যাক্টর বলে মনে হচ্ছে JUL (ধীর) এবং এসএলএফ 4 জে + লগব্যাক (দ্রুত) এর মধ্যে বাস্তব পারফরম্যান্সের পার্থক্যের ক্ষেত্রে। ঠিক যেমন সিকি বলেছিলেন।
আমি আর একটি জিনিসও দেখতে পাচ্ছি যে এসএলএফ 4 জে getLogger()
কলটি জুলের ডাইটোর চেয়ে অনেক বেশি ব্যয়বহুল। (আমার প্রোফাইলার সঠিক হলে 95 এমএস বনাম 0.3 এমএস)। এইবার বুঝতে পারছি. এসএলএফ 4 জে অন্তর্নিহিত লগিং প্রয়োগের বাঁধাইয়ের জন্য কিছু সময় করতে হবে। এটি আমাকে ভয় দেয় না। কোনও অ্যাপ্লিকেশন চলাকালীন এই কলগুলি কিছুটা বিরল হওয়া উচিত। দৃness়তা আসল লগ কলগুলিতে হওয়া উচিত।
চূড়ান্ত উপসংহার
(08-JUL-2012-এ nolan600 দ্বারা বিভাগ যুক্ত করা হয়েছে)
আপনার সমস্ত উত্তরের জন্য আপনাকে ধন্যবাদ। আমি প্রথমে যা ভেবেছিলাম তার বিপরীতে আমি আমার API এর জন্য SLF4J ব্যবহার করার সিদ্ধান্ত নিয়েছে। এটি বিভিন্ন জিনিস এবং আপনার ইনপুট উপর ভিত্তি করে:
এটি স্থাপনার সময়ে লগ প্রয়োগকরণ চয়ন করার জন্য নমনীয়তা দেয়।
অ্যাপ্লিকেশন সার্ভারের ভিতরে চলাকালীন JUL এর কনফিগারেশনের নমনীয়তার অভাবজনিত সমস্যা।
আপনি যদি লগব্যাকের সাথে দম্পতি করেন তবে এসএলএফ 4 জে অবশ্যই উপরে উপরে বিস্তারিত হিসাবে অনেক দ্রুতগতিযুক্ত। এমনকি এটি যদি মোটামুটি পরীক্ষা ছিল তবেও আমার বিশ্বাস করার কারণ আছে যে জুলুয়ালের চেয়ে এসএলএফ 4 জে + লগব্যাকের ক্ষেত্রে আরও অনেক প্রচেষ্টা অপ্টিমাইজেশনে চলে গেছে।
নথিপত্র। এসএলএফ 4 জেয়ের জন্য ডকুমেন্টেশনটি কেবল আরও অনেক বিস্তৃত এবং সুনির্দিষ্ট।
প্যাটার্ন নমনীয়তা। আমি যেমন পরীক্ষাগুলি করেছিলাম তখন আমি লুলব্যাক থেকে জুলের ডিফল্ট প্যাটার্নটি নকল করবো। এই প্যাটার্নটিতে থ্রেডের নাম অন্তর্ভুক্ত রয়েছে। দেখা যাচ্ছে JUL বাক্সের বাইরে এটি করতে পারে না। ঠিক আছে, আমি এখন অবধি এটি মিস করি না, তবে আমি মনে করি না যে এটি এমন জিনিস যা লগ ফ্রেমওয়ার্ক থেকে হারিয়ে যাওয়া উচিত। সময়কাল!
বেশিরভাগ (বা অনেক) জাভা প্রকল্পগুলি আজ মাভেনকে ব্যবহার করে তাই নির্ভরতা যুক্ত করা বড় বিষয় নয় বিশেষত যদি সেই নির্ভরতা বরং স্থিতিশীল হয়, অর্থাৎ ক্রমাগতভাবে তার এপিআই পরিবর্তন করে না। এটি এসএলএফ 4 জেতে সত্য বলে মনে হচ্ছে। এছাড়াও এসএলএফ 4 জার এবং বন্ধুরা আকারে ছোট।
সুতরাং অদ্ভুত যে ঘটনাটি ঘটেছে তা হ'ল আমি আসলে এসএলএফ 4 জে কিছুটা কাজ করার পরে জুলুলের সাথে বেশ বিরক্ত হয়েছিলাম। আমি এখনও আফসোস করছি যে এটি জুলাইয়ের সাথে এইভাবেই হতে হবে। JUL নিখুঁত থেকে দূরে কিন্তু ধরনের কাজ করে। যথেষ্ট যথেষ্ট ভাল না। Properties
উদাহরণ হিসাবে এটি সম্পর্কেও বলা যেতে পারে তবে আমরা বিমূর্ত সম্পর্কে চিন্তা করি না যাতে লোকেরা তাদের নিজস্ব কনফিগারেশন লাইব্রেরিতে এবং আপনার কাছে কী থাকতে পারে। আমি মনে করি যে কারণটি Properties
বারের ঠিক উপরে এসেছিল যখন বিপরীতে আজকের জুলের পক্ষে সত্য ... এবং অতীতে এটি শূন্যে এসেছিল কারণ এটি বিদ্যমান ছিল না।
java.lang.System.Logger
, যা এটি চালু হয়েছিল , এটি একটি ইন্টারফেস , যা আপনি যতটা প্রকৃত লগিং ফ্রেমওয়ার্কটি চান তা পুনঃনির্দেশিত করা যেতে পারে, যতক্ষণ না সেই কাঠামোটি ধরা পড়ে এবং সেই ইন্টারফেসটির বাস্তবায়ন সরবরাহ করে। মডুলারাইজেশনের সাথে সম্মিলিত, আপনি এমনকি java.util.logging
যদি কোনও আলাদা কাঠামো পছন্দ করেন তবে আপনি একটি বান্ডিলযুক্ত জেআরই নেই এমন একটি অ্যাপ্লিকেশন স্থাপন করতে পারেন।