مكتبة Java مفتوحة المصدر مع تصفية stacktrace ، تحليل سلسلة الصامت ومقارنة الإصدار

خلال بعض الوقت في وظائف مختلفة ، واجهت العديد من الأدوات المساعدة التي لم أجدها متوفرة في ذلك الوقت. ورأيت أنني في حاجة إليها عدة مرات مرارًا وتكرارًا. لذلك كتبت مكتبتي الصغيرة التي وجدتها مفيدة للغاية. لذلك نشرت للتو كمكتبة جافا مفتوحة المصدر.

هنا هو الرابط جيثب

Javadoc على الانترنت متاح هنا

أيضا ، تتوفر هذه المكتبة في Maven Central. فيما يلي بعض التحف Maven (الإصدار 1.5.0.8 هو الأحدث في وقت كتابة هذا المقال ولكنه قد يتغير في المستقبل. للتحقق من أحدث إصدار ، ابحث عن قطعة أثرية "MgntUtils" على الموقع http: //search.maven. غزاله / ):

<dependency> <groupId>com.github.michaelgantman</groupId> <artifactId>MgntUtils</artifactId> <version>1.5.0.8</version> </dependency> <dependency> <groupId>com.github.michaelgantman</groupId> <artifactId>MgntUtils</artifactId> <version>1.5.0.8</version> <classifier>javadoc</classifier> </dependency> <dependency> <groupId>com.github.michaelgantman</groupId> <artifactId>MgntUtils</artifactId> <version>1.5.0.8</version> <classifier>sources</classifier> </dependency> 

أدناه هو مجرد شرح قصير لما هو موجود. تأتي المكتبة مع JavaDoc مكتوب بشكل جيد (آمل) مع وصف تفصيلي. حتى هنا قائمة الميزات:

Stacktrace مرشح الضوضاء


في تجربتي ، كانت هذه الميزة الأكثر عمومية ومفيدة بالنسبة لي. Stacktrace هو المنقذ عند تصحيح الأخطاء أو محاولة معرفة الخطأ الذي حدث في التطبيق الخاص بك. ومع ذلك ، عند العمل مع السجلات على جانب الخادم ، يمكنك العثور على stacktrace الضخمة التي تحتوي على أطول ذيل عديم الفائدة من مختلف الأطر والحزم ذات الصلة بـ Application Server. وفي مكان ما في هذا الكومة ، هناك عدة سطور تتبع ذات صلة وقد تكون في شرائح مختلفة مفصولة بمعلومات غير مجدية. يصبح كابوسا للبحث عن الأشياء ذات الصلة. في ما يلي رابط يصف المشكلة نفسها بأمثلة من واقع الحياة (وليس للمتخوفين) https://dzone.com/articles/filtering-stack-trace-hell . لذلك في مكتبتي ، هناك فئة تسمى TextUtils ولها طريقة getStacktrace () مع العديد من التواقيع الزائدة. يستغرق مثيل Throwable ويسمح بتعيين بادئة الحزمة من الحزم ذات الصلة.

أيضا ، فإن الأداة المساعدة نفسها (بدءا من الإصدار 1.5.0.3) لديها getStacktrace () طريقة تأخذ واجهة CharSequence بدلا من Throwable ، وبالتالي تسمح لتصفية وتقصير stacktrace المخزنة كسلسلة بنفس طريقة تكديس المستخرجة من Throwable. لذلك ، يمكن تصفية مكدسات الأساس "سريعًا" في وقت التشغيل أو لاحقًا من أي مصدر نصي مثل السجل. (فقط للتوضيح - لا تدعم الأداة المساعدة تحليل ملف السجل بأكمله وتعديله. إنها تدعم التصفية فقط لتكوّن stacktrace كما تم تمريره كسلسلة. لذلك إذا أراد أي شخص تصفية الاستثناءات في ملف السجل ، فسيتعين عليه تحليل ملف السجل ثم استخراج stacktrace (s) كسلسلة منفصلة ومن ثم يمكن استخدام هذه الأداة المساعدة لتصفية كل stacktrace الفردية).

هنا مثال للاستخدام. دعنا نقول أن رمز شركتك موجود دائمًا في الحزم التي تبدأ بـ "com.plain. *" لذا ، يمكنك تعيين هذه البادئة والقيام بذلك

 logger.info(TextUtils.getStacktrace(e,true,"com.plain.")); 

سيؤدي ذلك إلى تصفية جميع الأجزاء غير المجدية في التتبع بذكاء ، مما يتركك بتجميع موجز للغاية. أيضًا ، وجدت أنه من المناسب جدًا تعيين البادئة مسبقًا ثم استخدام طريقة الراحة فقط

 TextUtils.getStacktrace(e); 

سوف تفعل الشيء نفسه. لضبط البادئة فقط استخدم الطريقة

 setRelevantPackage("com.plain."); 

إذا كنت ترغب في ضبط هذه القيمة مسبقًا من خلال التكوين ثم البدء بإصدار المكتبة 1.1.0.1 ، يمكنك ضبط "متغير البيئة" " MGNT_RELEVANT_PACKAGE " أو خاصية النظام " mgnt.relevant.package " على القيمة " com.plain " . والخاصية سيتم تعيينها على تلك القيمة بدون استدعاء الأسلوب TextUtils.setRelevantPackage ("com.plain.")؛ صراحة في التعليمات البرمجية الخاصة بك. لاحظ أن قيمة خاصية النظام سيكون لها الأسبقية على متغير البيئة إذا تم تعيين كليهما. مجرد تذكير أنه مع خاصية النظام يمكنك إضافته في سطر الأوامر باستخدام علامة -D:

"-Dmgnt.relevant.package = com.plain."

أيضًا ، إذا كنت تستخدم إصدارًا أقدم من الإصدار 1.1.0.1 من هذه المكتبة أو إذا كنت لا تريد استخدام متغير البيئة أو خاصية النظام المذكورة أعلاه وكنت تستخدم بيئة Spring ، فيمكنك ضبط البادئة مسبقًا عن طريق إضافة المقطع التالي إلى تهيئة Spring لديك:

 <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="targetClass" value="com.mgnt.utils.TextUtils"/> <property name="targetMethod" value="setRelevantPackage"/> <property name="arguments" value="com.plain."/> </bean> 

يشرح Javadoc كل شيء بالتفصيل. ولكن هنا دعابة بعض الشيء: سوف تحصل على stacktrace التالية:

 at com.plain.BookService.listBooks() at com.plain.BookService$$FastClassByCGLIB$$e7645040.invoke() at net.sf.cglib.proxy.MethodProxy.invoke() ... at com.plain.LoggingAspect.logging() at sun.reflect.NativeMethodAccessorImpl.invoke0() ... at com.plain.BookService$$EnhancerByCGLIB$$7cb147e4.listBooks() at com.plain.web.BookController.listBooks() 

بدلا من

 at com.plain.BookService.listBooks() at com.plain.BookService$$FastClassByCGLIB$$e7645040.invoke() at net.sf.cglib.proxy.MethodProxy.invoke() at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint() at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed() at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed() at com.plain.LoggingAspect.logging() at sun.reflect.NativeMethodAccessorImpl.invoke0() at sun.reflect.NativeMethodAccessorImpl.invoke() at sun.reflect.DelegatingMethodAccessorImpl.invoke() at java.lang.reflect.Method.invoke() at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs() at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod() at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke() at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed() at org.springframework.aop.interceptor.AbstractTraceInterceptor.invoke() at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed() at org.springframework.transaction.interceptor.TransactionInterceptor.invoke() at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed() at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke() at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed() at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept() at com.plain.BookService$$EnhancerByCGLIB$$7cb147e4.listBooks() at com.plain.web.BookController.listBooks() 

تحليل سلسلة صامتة إلى عدد صحيح ، طويل ، إلخ


توفر الفئة TextUtils نفسها طرقًا لتحليل "السلسلة" بصمت (دون استثناء) في أنواع "مزدوج" و "طويل" و "عدد صحيح" و "قصير" و "بايت". تسمى الأساليب parseStringToLong () parseStringToInteger () إلخ. يأخذون كل 4 حجج:

  1. سلسلة لتحليلها
  2. تطبيق الرقم (مزدوج ، طويل ، عدد صحيح ، قصير أو بايت) ليكون بمثابة قيمة افتراضية في حالة حدوث أي مشكلة في التحليل
  3. سلسلة سيتم طباعتها كرسالة خطأ في السجل إذا كانت الوسيطة الأولى خالية (قد تكون خالية ، ثم لم تتم طباعة أي خطأ)
  4. سلسلة سيتم طباعتها كرسالة خطأ في حالة حدوث NumberFormatException (قد تكون فارغة ، ثم لا تتم طباعة أي خطأ)

تحليل سلسلة إلى الفاصل الزمني


في نفس الفئة TextUtils ، هناك طريقة parseStringToTimeInterval (قيمة السلسلة) . هذا الأسلوب يوزع سلسلة يتوقع أن يحتفظ ببعض قيمة الفاصل الزمني - قيمة رقمية مع وحدة زمنية اختيارية. على سبيل المثال ، سيتم تحليل السلسلة "38s" على 38 ثانية ، "24m" - 24 دقيقة "4h" - 4 ساعات ، "3d" - 3 أيام و "45" إلى 45 مللي ثانية. اللواحق المدعومة هي " s " للثواني ، " m " للدقائق ، " h " لساعات و " d " لعدة أيام. تعتبر السلسلة بدون لاحقة تحمل قيمة بالمللي ثانية. اللواحق غير حساسة لحالة الأحرف. إذا تم توفير سلسلة تحتوي على لاحقة غير مدعومة أو تحتوي على قيمة رقمية سالبة أو صفر أو تحمل قيمة غير رقمية - يتم طرح IllegalArgumentException. تقوم هذه الطريقة بإرجاع فئة TimeInterval - فئة معرفة أيضًا في هذه المكتبة. بشكل أساسي ، فإنه يحتفظ بخاصيتين مع أدوات التلاعب والتركيب ذات الصلة: "القيمة" الطويلة و java.util.concurrent.TimeUnit. ولكن بالإضافة إلى getters و setters هذه الفئة لديها أساليب toMillis () و toSeconds () و toMinutes () و toHours () toDays () . تقوم هذه الطرق بإرجاع قيمة طويلة في مقياس زمني محدد (بنفس الطريقة المتبعة في الأساليب المقابلة في الفئة java.util.concurrent.TimeUnit )

قد تكون هذه الطريقة مفيدة للغاية في تحليل خصائص الفاصل الزمني مثل المهلات أو فترات الانتظار من ملفات التكوين. فإنه يلغي الحسابات غير الضرورية من جداول زمنية مختلفة إلى ميلي ثانية ذهابا وإيابا. ضع في اعتبارك أن لديك خاصية methodInvokingInterval تحتاج إلى تعيينها لمدة 5 أيام. لذلك من أجل تعيين قيمة المللي ثانية ، ستحتاج إلى حساب أن 5 أيام هي 432000000 مللي ثانية (من الواضح أنها ليست مهمة مستحيلة ولكن مزعجة وعرضة للخطأ) وبعد ذلك أي شخص آخر يرى القيمة 432000000 سيضطر إلى حسابها مرة أخرى إلى 5 الأيام التي هي محبطة. لكن باستخدام هذه الطريقة ، سيكون لديك قيمة خاصية تم ضبطها على "5d" واستدعاء الكود

 long milliseconds = TextUtils.parsingStringToTimeInterval("5d").toMillis(); 

سوف يحل مشكلة التحويل الخاصة بك. من الواضح أن هذه ليست ميزة معقدة للغاية ، ولكنها يمكن أن تضيف البساطة والوضوح في ملفات التكوين الخاصة بك وتحفظ بعض الإحباط وسوء التقدير "الغبي" في الأخطاء بالميلي ثانية.

مقارنة الإصدارات


تتيح هذه الأداة المساعدة تحويل السلسلة إلى إصدار والعكس بالعكس ومقارنة الإصدارات ونطاقات الإصدار بشكل صحيح. في كثير من الأحيان ، إذا كنت بحاجة إلى مقارنة الإصدارات ، يمكنك فقط مقارنة السلاسل. لنفترض أن الإصدار "1.5.3" سيكون أكبر من الإصدار "1.3.1". ومع ذلك ، إذا قمت بمقارنة السلاسل "1.4.2" و "1.12.3" فإن السلسلة "1.4.2" ستكون خطأ أكبر. لذلك تهتم هذه الأداة المساعدة بمثل هذه المشكلة ، بالإضافة إلى ذلك ، تقدم فئة VersionRange وتسمح بالعمليات على نطاقات الإصدار. (راجع طرق المقارنة في الإصدارات TextUtils والفئة VersionRange )

سلسلة يونيكود محول


Class StringUnicodeEncoderDecoder لديه طرق يمكنها تحويل سلسلة (بأي لغة) إلى سلسلة من أحرف Unicode والعكس بالعكس. على سبيل المثال ، سيتم تحويل السلسلة "Hello World" إلى

"\ u0048 \ u0065 \ u006c \ u006c \ u006f \ u0020 \ u0057 \ u006f \ u0072 \ u006c \ u0064"

ويمكن استعادتها مرة أخرى.

إدارة دورة حياة (مصانع ذاتية التأسيس)


هذه الميزة عبارة عن حزمة تحتوي على بعض البنية التحتية الصغيرة التي تعمل على تبسيط وأتمتة العمل مع المصانع التي توفر تطبيقات ملموسة للواجهة. تحتوي الحزمة على فئتين فقط: BaseEntityFactory و BaseEntity . باختصار ، ما تفعله هذه البنية التحتية هو أنه إذا قمت بإنشاء مصنع يمتد BaseEntityFactory وبعض الواجهات مع جميع تطبيقاته الملموسة التي تمتد BaseEntity ، فسيتم تلقائيًا إدراج كل مثيل من فئة فئة التنفيذ الملموسة في المصنع الخاص بك. لن تضطر للقلق بشأن كيفية ووقت ملء مصنعك. ستقوم البنية التحتية بذلك نيابة عنك عندما يتم استدعاء مُنشئ فئة التنفيذ الملموسة. لذلك كل ما عليك القيام به هو إنشاء أي عدد من فئات التنفيذ الملموسة والتأكد من استدعاء كل مُنشئ واحد. بعد ذلك ، يمكنك استخدام المصنع الخاص بك للحصول على أي من فئات التنفيذ الخاصة بك في أي مكان في التعليمات البرمجية الخاصة بك. هذا شرح قصير. هناك القليل من التفاصيل ولكن ليس الكثير. للحصول على وصف مفصل لهذه الحزمة ، يرجى الرجوع إلى واجهة برمجة تطبيقات Javadoc للحزمة com.mgnt.lifecycle.management . أيضًا ، يحتوي الكود المصدري على حزمة com.mgnt.lifecycle.management.example التي تحتوي على مثال تعليمي مفصل ومعلق بشكل جيد حول كيفية استخدام هذه الميزة.

أما بالنسبة للاستخدام العملي ، فقد وجدت أنه مفيد جدًا لإطار Spring. تذكر أن Spring ينبثق كل الفاصوليا المحددة أثناء التهيئة. لذا ، في سياق Spring ، إذا أعلنا ببساطة عن تطبيقاتنا الملموسة على أنها فاصوليا Spring ، فستقوم Spring بتثبيتها من أجلنا ، وبالتالي تهيئة مصنعها تلقائيًا. هذا يمكن أن يكون مريحة للغاية. تخيل أن لديك بعض الحبات التي لها خاصية من نوع واجهة المستخدم المعرفة والتي لديها عدة تطبيقات ، ولكن يتم تحديد التنفيذ الفعلي المطلوب في وقت التشغيل. لذلك في ذلك الوقت ، يمكنك استخدام getInstance (java.lang.String) لمصنعك للوصول إلى التطبيق المطلوب. سيسمح لك ذلك بعدم حقن كل ما تبذلونه من مثيليات ملموسة في الفول الخاص بك ولن تضطر إلى استخدام Spring Bean Factory للوصول إلى فاصوليا معرفة بالزنبرك لأن ذلك من شأنه أن ينتهك عدم تدخيل Spring (مما يعني أنه يمكنك كتابة مكونات لا تعتمد على الربيع). أيضًا ، إذا كنت بحاجة في مرحلة لاحقة إلى إضافة المزيد من التطبيقات الملموسة ، فكل ما عليك فعله هو إضافة فئات التنفيذ الخاصة بك إلى الكود الخاص بك وإعلانها على أنها حبوب الربيع. وسيتم تنفيذ الباقي بحلول الربيع وهذه البنية التحتية!

ملف utils


تتيح هذه الأداة المساعدة قراءة ملف كسلسلة مع أو بدون تحديد مجموعة أحرف أو مجرد قراءتها كصفيف بايت. هذه الأداة تستخدم حزمة nio والمخازن المؤقتة لأداء أسرع. حجم الملف الأقصى لهذه الأداة هو 2G.

استخدام الوقت


هذه مجرد وسيلة راحة واحدة توفر نفس وظيفة Thread.sleep () لكنها صامتة. أي أنه "يبتلع" IterruptedException. أيضًا ، يستغرق الأمر وسيطين: وقت النوم ووحدة القياس. لذلك بدلا من

 try { Thread.sleep(2000); } catch (InterruptedException ie) { } 

يمكنك فقط الكتابة:

 TimeUtils.sleepFor(2, TimeUnit.SECONDS); 

اعتقدت انه كان لطيفا

لذلك هذا هو عليه. لا تتردد في تحميل هذه المكتبة. إنه يأتي مع ترخيص MIT - أحد أكثر التراخيص المسموح بها التي أعرفها. شفرة المصدر ، Javadoc والإصدار الثنائي متاح في الرابط أعلاه. تمت ترجمة الرمز بواسطة JDK 8 ولكن لا يحتوي على ميزات الإصدار 8 فيه. يجب أن يعمل مع java 7 بكل تأكيد ، وأظن أنه سيعمل مع java 6 وحتى 5 ، ولكن لم نختبرها مع تلك الإصدارات. لا تتردد في استخدامه كما تراه مناسبًا ، وأخبر الآخرين به إذا كنت ترغب في ذلك ، ولا تتردد في إرسال ملاحظة لي على michael_gantman@yahoo.com إذا كان لديك أي ملاحظات.

Source: https://habr.com/ru/post/ar480268/


All Articles