স্কালায় লগইন হচ্ছে


168

স্কালার অ্যাপ্লিকেশনটিতে লগ ইন করার একটি ভাল উপায় কী? ভাষা দর্শনের সাথে সামঞ্জস্যপূর্ণ এমন কোনও কিছু কোডকে বিশৃঙ্খলা করে না এবং স্বল্প রক্ষণাবেক্ষণ এবং স্ববিরোধী। এখানে একটি প্রাথমিক প্রয়োজন তালিকা:

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

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

আপনার জবাবের জন্য ধন্যবাদ।

উত্তর:


119

slf4j মোড়ক

স্কালার বেশিরভাগ লগইন লাইব্রেরি জাভা লগিং ফ্রেমওয়ার্ক (এসএলএফ 4 জে, লগ 4 জে ইত্যাদি) এর আশেপাশে কিছু মোড়ক তৈরি করেছে তবে মার্চ ২০১৫ পর্যন্ত বেঁচে থাকা লগ লাইব্রেরিগুলি সমস্ত slf4j are এই লগ লাইব্রেরি কিছু বাছাই প্রদান logবস্তুর জন্য আপনি কল করতে পারেন info(...), debug(...)ইত্যাদি আমি slf4j একটি বড় অনুরাগী নই, কিন্তু এটা এখন উদীয়মান লগিং কাঠামো মনে করা হয়। এখানে এসএলএফ 4 এর বর্ণনা রয়েছে :

জাভা বা (এসএলএফ 4 জে) জন্য সিম্পল লগিং ফেকাড বিভিন্ন লগিং ফ্রেমওয়ার্কগুলির জন্য যেমন একটি সহজ ফ্যাসাদ বা বিমূর্ততা হিসাবে কাজ করে, যেমন java.util.logging, log4j এবং লগব্যাক, শেষ ব্যবহারকারীকে মোতায়েনের সময় কাঙ্ক্ষিত লগিং ফ্রেমওয়ার্কটিতে প্লাগ করতে দেয়।

স্থাপনার সময়ে অন্তর্নিহিত লগ লাইব্রেরিটি পরিবর্তন করার ক্ষমতা লগারের পুরো slf4j পরিবারে অনন্য বৈশিষ্ট্য নিয়ে আসে, যার সম্পর্কে আপনার সচেতন হওয়া দরকার:

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

একটি বড় প্রকল্পে, প্রত্যেকে যদি slf4j ব্যবহার করে তবে ট্রানজিটিভ নির্ভরতার লগিং আচরণটি নিয়ন্ত্রণ করতে সক্ষম হওয়াই সুবিধাজনক হতে পারে।

স্কালাল লগিং

স্কালা লগিং তাঁর এসএফ 4 এর উত্তরসূরি হিসাবে হাইকো সিবার্গার লিখেছেন । সম্ভাব্য ব্যয়বহুল লগ কল এড়ানোর জন্য যদি অভিব্যক্তিটি কলগুলিতে প্রসারিত করতে ম্যাক্রো ব্যবহার করে।

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

.তিহাসিক লগার

  • লোগুলা , কোডা হেলে রচিত লগ 4 জে র‍্যাপার। এটি পছন্দ করতেন তবে এখন এটি পরিত্যক্ত।
  • কনফিগার , একটি java.util.logging মোড়ক যা স্কালার আগের দিনগুলিতে জনপ্রিয় ছিল। এখন পরিত্যক্ত।

1
বলতে হবে, আমি লোগুলাকে ভালবাসি ... অবশেষে এমন একটি লগার যা আমাকে কানের কাছে স্ক্রু ড্রাইভার চালাতে চায় না। কোন XML এবং কোন বিএস, সূচনার সময় শুধু a Scala কনফিগ
Arg

হাইকো সিবার্গারের এসএলএফ 4 এস আর রক্ষণাবেক্ষণের জন্য প্রদর্শিত হয় না। আমি নিজের টার্গেট করে স্কেলা ২.১০ এবং সর্বশেষতম এসএলএফ ৪ জে তৈরি করেছি। http://slf4s.org/
ম্যাট রবার্টস

3
গিথুবটিতে তার README অনুসারে লোগুলা পরিত্যক্ত হয়।
এরিক কাপলুন

স্কেল লগিংয়ের ক্ষেত্রে অনকি জার্নালটি একই রকম, তবে লগ বার্তা এমন অভিনেতার কাছে প্রেরণ করা হয় যা ডেডিকেটেড থ্রেড পুল থেকে এসএলএফ 4 জে ফোন করে calls ট্রেডস সিপিইউ সময় (অনেক ভাল) বিলম্বের জন্য। github.com/oncue/jorter
গ্যারি Coady

64

স্কেলা ২.১০+ সহ টাইপসেফের মাধ্যমে স্কেললগিং বিবেচনা করুন। খুব ক্লিন এপিআই সরবরাহ করতে ম্যাক্রোগুলি ব্যবহার করে

https://github.com/typesafehub/scala-logging

তাদের উইকি থেকে উদ্ধৃতি:

ভাগ্যক্রমে স্কালা ম্যাক্রোগগুলি আমাদের জীবনকে আরও সহজ করার জন্য ব্যবহার করা যেতে পারে: স্কালালগিং Loggerলাইটওয়েট লগিং পদ্ধতি সহ শ্রেণীর অফার করে যা উপরের আইডিয়োমে প্রসারিত হবে। সুতরাং আমাদের যা লিখতে হবে তা হ'ল:

logger.debug(s"Some ${expensiveExpression} message!")

ম্যাক্রো প্রয়োগ হওয়ার পরে কোডটি উপরের বর্ণিত আইডিয়োমে রূপান্তরিত হবে।

এছাড়াও স্কেললগিং বৈশিষ্ট্যটি সরবরাহ করে Loggingযা সুবিধামত Loggerমিশ্রিত শ্রেণীর নাম দিয়ে প্রাথমিকভাবে একটি উদাহরণ সরবরাহ করে:

import com.typesafe.scalalogging.slf4j.LazyLogging

class MyClass extends LazyLogging {
  logger.debug("This is very convenient ;-)")
}

12
ব্যবহার class MyClass with Logging
আন্দ্রেজেজ জোজউইক

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

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

2
আপনি একটি লগার ক্ষেত্র পাবেন, যা আপনি আপনার অবসর সময়ে ব্যবহার করতে পারেন। দেখুন github.com/typesafehub/scalalogging/blob/master/... বিস্তারিত জানার জন্য
fracca

2
2.x এর জন্য স্কেলা 2.11 প্রয়োজন; আশা করি তেমন ব্যবহারিক পার্থক্য নেই; স্কেল ২.১০.x এর জন্য রয়েছে "com.typesafe" %% "scalalogging-slf4j" % "1.1.0"
এরিক কাপলুন

14

Slf4j এবং একটি মোড়ক ব্যবহার করা দুর্দান্ত তবে এটি দ্বিখণ্ডিতভাবে নির্মিত যখন এটির দ্বিখণ্ডিতকরণের জন্য দুটিরও বেশি মান রয়েছে তখন থেকে আপনাকে বিয়োগের জন্য মানগুলির একটি অ্যারে তৈরি করতে হবে।

সমাধানের মতো আরও একটি স্কেল হ'ল ত্রুটি বার্তার সংক্ষিপ্তকরণটি বিলম্ব করতে একটি থঙ্ক বা ক্লাস্টার ব্যবহার করা। এর একটি ভাল উদাহরণ লিফ্টের লগার

লগ.স্কালা Slf4jLog.scala

যা দেখতে এরকম দেখাচ্ছে:

class Log4JLogger(val logger: Logger) extends LiftLogger {
  override def trace(msg: => AnyRef) = if (isTraceEnabled) logger.trace(msg)
}

মনে রাখবেন যে এই চিত্রটি একটি কল-বাই নাম এবং এটির ট্রেসইনবেলড সত্য না হলে মূল্যায়ন করা হবে না সুতরাং একটি সুন্দর বার্তার স্ট্রিং তৈরিতে কোনও খরচ নেই। এটি slf4j এর ইন্টারপোলেশন প্রক্রিয়াটির চারপাশে কাজ করে যার জন্য ত্রুটি বার্তাকে পার্স করা প্রয়োজন। এই মডেলটির সাহায্যে আপনি ত্রুটি বার্তায় যে কোনও মানকে সংযোজন করতে পারেন।

যদি আপনার একটি পৃথক বৈশিষ্ট্য থাকে যা এই লোগ 4 জে লোগারটিকে আপনার শ্রেণিতে মিশ্রিত করে, তবে আপনি এটি করতে পারেন

trace("The foobar from " + a + " doesn't match the foobar from " +
      b + " and you should reset the baz from " + c")

পরিবর্তে

info("The foobar from {0} doesn't match the foobar from {1} and you should reset the baz from {c},
     Array(a, b, c))

2
স্কেলা ক্লাসে বিবৃতি লগ করার জন্য সঠিক লাইন নম্বর পাওয়া সম্ভব ?????
jpswain

13

লোগুলা ব্যবহার করবেন না

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

Slf4s + slf4j- সহজ ব্যবহার করুন

কী উপকারিতা:

  • সর্বশেষ স্কেল 2.10 সমর্থন করে (এখনও এটি এম 7 রয়েছে)
  • কনফিগারেশন বহুমুখী তবে সহজ হতে পারে না। এটা দিয়ে সম্পন্ন সিস্টেম বৈশিষ্ট্য , আপনি ভালো কিছু সংযোজন করে পারেন সেট করতে পারেন যা -Dorg.slf4j.simplelogger.defaultlog=traceআপনার স্ক্রিপ্টের মধ্যে সঞ্চালনের আদেশ বা হার্ডকোড করুন: System.setProperty("org.slf4j.simplelogger.defaultlog", "trace")। ট্র্যাসি কনফিগারেশন ফাইলগুলি পরিচালনা করার দরকার নেই!
  • আইডিই সহ সুন্দরভাবে ফিট করে। উদাহরণস্বরূপ আইডিইএতে একটি নির্দিষ্ট রান কনফিগারেশনে লগিং স্তরটিকে "ট্রেস" তে সেট করতে কেবল যান Run/Debug Configurationsএবং এতে যুক্ত -Dorg.slf4j.simplelogger.defaultlog=traceহন VM options
  • সহজ সেটআপ: এই উত্তরের নীচে থেকে নির্ভরতাগুলি সরিয়ে ফেলুন

মাভেনের সাথে এটি চালানো আপনার যা দরকার তা এখানে:

<dependency>
  <groupId>com.weiglewilczek.slf4s</groupId>
  <artifactId>slf4s_2.9.1</artifactId>
  <version>1.0.7</version>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-simple</artifactId>
  <version>1.6.6</version>
</dependency>

আপনি যেখানে সল্ফ 4 গুলি পাবেন যেখানে 2.10 সমর্থন করে? আমি github.com/weiglewilczek/slf4sদেখছি এবং "সমর্থিত স্কালার সংস্করণগুলি 2.8.0, 2.8.1, 2.9.0-1 এবং 2.9.1 দেখুন" " ..আমি কি ভুল জায়গায় দেখছি?
nairbv

@ ব্রায়ান উত্তরের পরামর্শ অনুযায়ী ২.৯.১ ব্যবহার করুন আমি এটি 2.10.0-M7- এর সাথে সুক্ষ্মভাবে কাজ করার পরীক্ষা করেছি
নিকিতা ভলকভ

আমি ২.৯.১ ব্যবহার করছি, আমি হাইলাইটেড "কী বেনিফিট" এবং এর অর্থ কী তা সম্পর্কে আমি আগ্রহী ছিলাম।
nairbv

লগিং গ্রন্থাগারগুলির সুবিধার জন্য প্রয়োজনীয়তার সাথে উত্তরগুলি সন্ধানের পরে, আমি এমন একটি নির্বাচন করি যা আমাকে আমদানি করার জন্য নির্ভরতা বলে। ধন্যবাদ স্যার.
তেওঁ

11

এইভাবে আমি আমার জন্য কাজ করে স্কালাল লগিং পেয়েছি :

এটি আপনার মধ্যে রাখুন build.sbt:

libraryDependencies += "com.typesafe.scala-logging" %% "scala-logging" % "3.7.2",
libraryDependencies += "ch.qos.logback" % "logback-classic" % "1.2.3"

তারপরে, এটি করার পরে sbt update, এটি একটি বন্ধুত্বপূর্ণ লগ বার্তা প্রিন্ট করে:

import com.typesafe.scalalogging._
object MyApp extends App with LazyLogging {
  logger.info("Hello there")
}

আপনি প্লে ব্যবহার করে থাকেন, আপনি যা করতে পারেন অবশ্যই কেবল import play.api.Loggerলগ বার্তা লেখার জন্য: Logger.debug("Hi")

আরও তথ্যের জন্য ডক্স দেখুন ।


আমি log4j.propertiesপ্রকল্প রিসোর্স ফোল্ডারটি তৈরি করার পরে কেবল আমার জন্য কাজ করেছি ।
নাদজিব মামি

7

আমি কিছুটা কাজ টানতে এর Loggingবৈশিষ্ট্য scalaxতৈরি করেছি এবং এমন একটি বৈশিষ্ট্য তৈরি করেছি যা একটি MessageFormat-basedগ্রন্থাগারকেও সংহত করেছিল ।

তারপরে স্টাফ জাতীয় ধরণের দেখায়:

class Foo extends Loggable {
    info( "Dude, I'm an {0} with {1,number,#}", "Log message", 1234 )
}

আমরা এখন পর্যন্ত পদ্ধতির পছন্দ করি।

বাস্তবায়ন:

trait Loggable {

    val logger:Logger = Logging.getLogger(this)

    def checkFormat(msg:String, refs:Seq[Any]):String =
        if (refs.size > 0) msgfmtSeq(msg, refs) else msg 

    def trace(msg:String, refs:Any*) = logger trace checkFormat(msg, refs)

    def trace(t:Throwable, msg:String, refs:Any*) = logger trace (checkFormat(msg, refs), t)

    def info(msg:String, refs:Any*) = logger info checkFormat(msg, refs)

    def info(t:Throwable, msg:String, refs:Any*) = logger info (checkFormat(msg, refs), t)

    def warn(msg:String, refs:Any*) = logger warn checkFormat(msg, refs)

    def warn(t:Throwable, msg:String, refs:Any*) = logger warn (checkFormat(msg, refs), t)

    def critical(msg:String, refs:Any*) = logger error checkFormat(msg, refs)

    def critical(t:Throwable, msg:String, refs:Any*) = logger error (checkFormat(msg, refs), t)

}

/**
 * Note: implementation taken from scalax.logging API
 */
object Logging {  

    def loggerNameForClass(className: String) = {  
        if (className endsWith "$") className.substring(0, className.length - 1)  
        else className  
    }  

    def getLogger(logging: AnyRef) = LoggerFactory.getLogger(loggerNameForClass(logging.getClass.getName))  
}

সুন্দর, যদিও এটি কাজ করতে আমার কিছু সমস্যা হচ্ছে - বিশেষত, আউটপুটটি (ডিফল্ট এসএলএফ 4 জে কনফিগারেশনে) সর্বদা নিম্নের মতো দেখায়, ক্লাসের পরিবর্তে লগবেবলটি প্রসারিত করা হয়: জুলাই 22, 2011 3:02:17 এএম redacted.util.Loggable $ শ্রেণির তথ্য তথ্য: কিছু বার্তা ... আপনি যে কোনও সুযোগ পেয়েছেন?
টোমর গ্যাবেল

6

আমি এসএলএফ 4 জে + লগব্যাক ক্লাসিক ব্যবহার করি এবং এটি এটির মতো প্রয়োগ করি:

trait Logging {
  lazy val logger = LoggerFactory.getLogger(getClass)

  implicit def logging2Logger(anything: Logging): Logger = anything.logger
}

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

class X with Logging {
    logger.debug("foo")
    debug("bar")
}

তবে অবশ্যই এই পদ্ধতির প্রতি ক্লাসে প্রতি লগার উদাহরণ ব্যবহার করা হয়।


4

আপনার স্কেলাক্স লাইব্রেরিতে একটি নজর রাখা উচিত: http://scalax.scalaforge.org/ এই লাইব্রেরিতে একটি লগিং বৈশিষ্ট্য রয়েছে, ব্যাকএন্ড হিসাবে sl4j ব্যবহার করে। এই বৈশিষ্ট্যটি ব্যবহার করে, আপনি বেশ সহজেই লগ করতে পারেন (কেবল বৈশিষ্ট্যের উত্তরাধিকার সূত্রে শ্রেণিতে লগার ক্ষেত্রটি ব্যবহার করুন)।


4

Writer, Monoidএবং একটি Monadবাস্তবায়ন।


5
আপনি কি বলতে চাইছেন ব্যাখ্যা করতে পারেন?
ডেভিড জে

এর সংমিশ্রণগুলি আপনার ফলাফলের সাথে একটি দুর্দান্ত "লগ" সংযুক্ত করতে পারে। আইএমও, এটি কিছুটা ওভারকিল। তবে আপনি যদি নতুন কোনও ব্লগ
টিজি।

@Tg। আপনার মন্তব্যের লিঙ্কটি মারা গেছে। ব্যবহার করুন blog.tmorris.net/posts/the-writer-monad-using-scala-example
jub0bs


3

দ্রুত এবং সহজ ফর্ম।

স্কেল ২.১০ বা তার বেশি:

import com.typesafe.scalalogging.slf4j.Logger
import org.slf4j.LoggerFactory
val logger = Logger(LoggerFactory.getLogger("TheLoggerName"))
logger.debug("Useful message....")

এবং বিল্ড.এসবিটি:

libraryDependencies += "com.typesafe" %% "scalalogging-slf4j" % "1.1.0"

স্কেলা 2.11+ এবং আরও নতুন:

import import com.typesafe.scalalogging.Logger
import org.slf4j.LoggerFactory
val logger = Logger(LoggerFactory.getLogger("TheLoggerName"))
logger.debug("Useful message....")

এবং বিল্ড.এসবিটি:

libraryDependencies += "com.typesafe.scala-logging" %% "scala-logging" % "3.1.0"

2

কিছুক্ষণের জন্য slf4s এবং লোগুলা ব্যবহার করার পরে, আমি লিখেছিলাম loglady, একটি সহজ লগিং বৈশিষ্ট্য মোড়ানো slf4j।

এটি পাইথনের লগিং লাইব্রেরির মতো একটি এপিআই সরবরাহ করে যা সাধারণ কেসগুলিকে (বেসিক স্ট্রিং, সাধারণ ফর্ম্যাটিং) তুচ্ছ করে তোলে এবং বয়লারপ্লেটের বিন্যাসকে এড়িয়ে চলে।

http://github.com/dln/loglady/


2

আমি কিছু ধরণের জাভা লগার ব্যবহার করে খুব সুবিধাজনক বলে মনে করি, উদাহরণস্বরূপ, সরল স্কেলার মোড়কের সাহায্যে স্ল4 জে, যা আমাকে এ জাতীয় সিনট্যাক্স এনে দেয়

val #! = new Logger(..) // somewhere deep in dsl.logging.

object User with dsl.logging {

  #! ! "info message"
  #! dbg "debug message"
  #! trace "var a=true"

}

আমার মতে জাভা প্রমাণিত লগিং ফ্রেমওয়ার্ক এবং স্কালার অভিনব বাক্য গঠনের খুব উপযোগী মিশ্রণ।


@ এসচেফ, ওহ, হ্যাঁ দুঃখিত। আমি প্রায় ভুলে গেছি। কয়েক দিন ধরে এই ইস্যুটি নিয়ে এটি দুর্দান্ত লড়াই ছিল, তবে দেখে মনে হচ্ছে এটি সত্যিই অসম্ভব। আমি # ব্যবহার করেছি! ! পরিবর্তে "তথ্য বার্তা"। আমি আমার উত্তর সম্পাদনা সম্পাদনা করব।
অ্যালেক্স পোবার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.