পরামিতি তালিকায় লগারের অবস্থান কী হওয়া উচিত [বন্ধ]


12

আমার কোডে আমি আমার অনেক ক্লাসে তাদের নির্মাণকারীর প্যারামিটার তালিকার মাধ্যমে একটি লগার ইনজেক্ট করি

আমি লক্ষ্য করেছি যে আমি এলোমেলোভাবে রেখেছি: কখনও কখনও এটি তালিকার প্রথম, কখনও শেষ এবং কখনও কখনও এর মধ্যে থাকে

আপনার কোন পছন্দ আছে? আমার অন্তর্দৃষ্টি বলে যে ধারাবাহিকতা এই ক্ষেত্রে সহায়ক এবং আমার ব্যক্তিগত অগ্রাধিকারটি এটিকে প্রথমে রাখা উচিত যাতে এটি নিখোঁজ হওয়ার সময় লক্ষ্য করা সহজ হয় এবং যখন সেখানে থাকে তখন এড়ানো সহজ।

উত্তর:


31

লগাররা যাকে আমরা "ক্রস কাটিং উদ্বেগ" বলি। তারা এ্যাসপেক্ট-ওরিয়েন্টেড প্রোগ্রামিংয়ের মতো কৌশলগুলিতে ফল দেয়; যদি আপনার কোনও শ্রেণীর বৈশিষ্ট্য সহ আপনার ক্লাসগুলি সাজানোর কোনও উপায় থাকে বা কিছু কোড বুনন সম্পাদন করা হয়, তবে আপনার অবজেক্টস এবং পরামিতি তালিকাগুলি "খাঁটি" রাখার সময় লগিংয়ের ক্ষমতা অর্জনের এটি একটি ভাল উপায়।

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

এই কারণে, লগিংয়ের উদ্দেশ্যে প্রতিটি ক্লাসে লগার পাসের পরিবর্তে আমি লগিংকে সিস্টেমের একটি প্রাকৃতিক অংশ তৈরি করতে পছন্দ করি। সুতরাং আমি সাধারণত যা করি তা হ'ল যথাযথ লগিং নেমস্পেসের উল্লেখ এবং কেবল আমার ক্লাসে লগারটি ব্যবহার করা।

আপনি যদি এখনও কোনও লগারে পাস করতে চান তবে আমার পছন্দ হ'ল আপনি এটিকে প্যারামিটার তালিকার শেষ প্যারামিটার তৈরি করে (যদি সম্ভব হয় তবে এটি একটি anচ্ছিক প্যারামিটার করুন)। এটি প্রথম প্যারামিটার হওয়ার ফলে কোনও অর্থ হয় না; প্রথম প্যারামিটারটি সবচেয়ে গুরুত্বপূর্ণ হওয়া উচিত, এটি ক্লাসের ক্রিয়াকলাপের সাথে সবচেয়ে প্রাসঙ্গিক।


11
+ +! লগারকে কনস্ট্রাক্টর পারম থেকে দূরে রাখুন; আমি একটি স্ট্যাটিক লগার পছন্দ করি তাই আমি জানি যে সবাই একই জিনিস ব্যবহার করছে
স্টিভেন এ। লো 21

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

@ComicSansMS: অবশ্যই প্লাস থ্রেডিং ইস্যু ইত্যাদি ঠিক একটি ব্যক্তিগত পছন্দ - "যতটা সম্ভব সহজ, তবে সহজ নয়";)
স্টিভেন এ। লো

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

@ স্লোথারিও: এটি একটি স্ট্যাটিক লগারের সৌন্দর্য। কোনও ধরণের ইঞ্জেকশন লাগবে না।
রবার্ট হার্ভে

7

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

foo(mandatory);
foo(mandatory, optional);
foo(mandatory, optional, evenMoreOptional);

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

addThreeToList = map (+3)

তবে অন্যান্য উত্তরে যেমন উল্লেখ করা হয়েছে, সম্ভবত আপনি সম্ভবত সিস্টেমের প্রতিটি শ্রেণীর যুক্তি তালিকায় লগারটি সুস্পষ্টভাবে পাস করতে চান না।


3

এই সমস্যাটি আপনি প্রকৃতপক্ষে ইঞ্জিনিয়ারিংয়ের জন্য অনেক বেশি সময় ব্যয় করতে পারেন।

ক্যানোনিকাল লগিং প্রয়োগকারী ভাষাগুলির জন্য, কেবলমাত্র প্রতিটি ক্লাসে সরাসরি ক্যানোনিকাল লগার ইনস্ট্যান্ট করুন।

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

ব্যক্তিগতভাবে আমি বরং একটি একক কংক্রিট লগিং প্রয়োগের সাথে লেগে থাকতাম এবং সিসলগে সমস্ত কিছু প্রেরণ করতাম। সমস্ত ভাল লগ বিশ্লেষণ সরঞ্জামগুলি একাধিক অ্যাপ সার্ভার থেকে সিসআউট লগগুলি একটি বিস্তৃত প্রতিবেদনে একত্রিত করতে সক্ষম।

যখন কোনও ফাংশন স্বাক্ষরে এক বা দুটি নির্ভরতা পরিষেবাগুলির পাশাপাশি কিছু "আসল" যুক্তি অন্তর্ভুক্ত থাকে, আমি নির্ভরতা শেষ রাখি:

int calculateFooBarSum(int foo, int bar, IntegerSummationService svc)

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

আপনি যদি নিজের অ্যাপ্লিকেশন জুড়ে নিজেকে এক ডজনেরও বেশি বা আরও নির্ভরতা ইনজেকশন করতে দেখেন তবে সম্ভবত সিস্টেমটি পৃথক সাবসিস্টেমগুলিতে বিভক্ত হওয়া দরকার (আমি মাইক্রো সার্ভিসেস বলার সাহস করব?)।


ক্যালকুলেটফুবারসাম কল করতে সম্পত্তি ইনজেকশন ব্যবহার করা আমার কাছে বিশ্রী মনে হয়।
একটি ফু

2

লগারগুলি একটি বিশেষ কেস কারণ সেগুলি আক্ষরিকভাবে সর্বত্র পাওয়া উচিত।

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

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


1

আমি তাদের সাথে একমত পোষণ করছি যে ক্লাসে উত্তীর্ণ হওয়ার পরিবর্তে লগারটি স্ট্যাটিকালি অ্যাক্সেস করা উচিত। তবে যদি আপনার কোনও শক্ত কারণ থাকে তবে আপনি এটিটি পাস করতে চান (সম্ভবত বিভিন্ন উদাহরণগুলি বিভিন্ন লোকেশন বা কোনও কিছুতে লগ করতে চান) তবে আমি আপনাকে পরামর্শ দেব যে আপনি এটি নির্মাণকারীর সাহায্যে পাস করবেন না বরং এটি করার জন্য একটি পৃথক কল করুন, উদাহরণস্বরূপ Class* C = new C(); C->SetLogger(logger);বরং চেয়েClass* C = new C(logger);

এই পদ্ধতিটিকে প্রাধান্য দেওয়ার কারণ হ'ল লগার ক্লাসের মূলত অংশ নয় বরং অন্য কোনও উদ্দেশ্যে ব্যবহৃত ইঞ্জেকশন বৈশিষ্ট্য। এটি নির্মাণকারীর তালিকায় রাখলে এটি শ্রেণীর প্রয়োজনীয়তা তৈরি করে এবং বোঝায় যে এটি শ্রেণীর আসল যৌক্তিক রাষ্ট্রের অংশ। এটি আশা করা যুক্তিসঙ্গত, উদাহরণস্বরূপ (বেশিরভাগ শ্রেণীর সাথে যদিও সমস্ত কিছু নেই), X != Yতবে যদি C(X) != C(Y)তা হয় তবে আপনি একই শ্রেণীর খুব উদাহরণগুলির সাথে তুলনা করতে পারলে আপনি লগার অসমতার পরীক্ষা করে নেবেন এমন সম্ভাবনা কম।


1
অবশ্যই এটির একটি অসুবিধা রয়েছে যে লগারটি কনস্ট্রাক্টরের কাছে অনুপলব্ধ।
বেন ভয়েগট

1
আমি এই উত্তরটি সত্যিই পছন্দ করি। এটি ক্লাসের একটি পার্শ্ব-উদ্বেগকে লগিং করে তোলে যা আপনাকে কেবল এটির ব্যবহার থেকে আলাদা করতে হবে। সম্ভাবনা হ'ল আপনি যদি প্রচুর ক্লাসের কনস্ট্রাক্টারে লগার যোগ করছেন তবে আপনি সম্ভবত নির্ভরতা ইনজেকশন ব্যবহার করছেন। আমি সমস্ত ভাষার জন্য কথা বলতে পারি না, তবে আমি সি # তে জানি, কিছু ডিআই বাস্তবায়ন সরাসরি সম্পত্তিগুলিতে (গেটর / সেটার) ইনজেকশনের ব্যবস্থা করে ।
jpmc26

@ বেনভয়েগ্ট: এটি সত্য, এবং এটি এটি না করার একটি হত্যাকারী কারণ হতে পারে তবে সাধারণত, আপনি লগিং সেট করতে যাওয়ার প্রতিক্রিয়া হিসাবে আপনি অন্য নির্মাণে করতে চাইলে করতে পারেন।
জ্যাক এইডলি

0

এটি উল্লেখ করার মতো, আমি অন্য উত্তরগুলি এখানে স্পর্শ করতে দেখিনি, তা হ'ল লগারটি সম্পত্তি বা স্ট্যাটিকের মাধ্যমে ইনজেকশনের মাধ্যমে শ্রেণিকে পরীক্ষা করা শক্ত (এআর) করে। উদাহরণস্বরূপ, আপনি যদি লগারটিকে সম্পত্তির মাধ্যমে ইনজেকশন তৈরি করেন তবে ল্যাগার ব্যবহারের পদ্ধতিটি পরীক্ষা করার সময় আপনাকে এখন লগারটি ইনজেক্ট করতে হবে। এর অর্থ আপনি সম্ভবত এটি নির্ধারক নির্ভরতা হিসাবে সেট করতে পারেন কারণ শ্রেণিটির এটির প্রয়োজন হয় না।

স্থিতিশীল নিজেকে একই ইস্যুতে ধার দেয়; যদি লগার কাজ না করে, তবে আপনার পুরো শ্রেণি ব্যর্থ হয় (যদি আপনার শ্রেণি লগার ব্যবহার করে) - যদিও লগার ক্লাসের দায়িত্বের 'অংশ' নয় - যদিও এটি সম্পত্তি ইনজেকশনের মতো প্রায় খারাপ নয় কারণ আপনি অন্তত জেনে থাকুন যে লগার একটি অর্থে সর্বদা "সেখানে" থাকে।

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


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

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

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

1
আমি সম্পত্তি ইনজেকশন বিরুদ্ধে বিতর্ক করছি। আমি অগত্যা এটি নির্মাণে ইনজেকশন ব্যবহারের পক্ষে পরামর্শ দিচ্ছি না। আমি কেবল এটিই বলছি যে আমার মতে এটি সম্পত্তি ইনজেকশনের চেয়ে পছন্দনীয়।
ড্যান প্যান্ট্রি

"এটা কি সম্ভব?" এছাড়াও, হ্যাঁ, আইএল বয়ন এমন একটি জিনিস যা বিদ্যমান এবং এটি শীর্ষ উত্তরে উল্লেখ করা হয়েছিল ... mono-project.com
ড্যান প্যান্ট্রি

0

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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.