หลีกเลี่ยง printStackTrace (); ใช้การโทรหาคนตัดไม้แทน


86

ในแอปพลิเคชันของฉันฉันใช้รหัสผ่าน PMD มันแสดงข้อความนี้ให้ฉัน:

  • หลีกเลี่ยง printStackTrace (); ใช้การโทรคนตัดไม้แทน

นั่นหมายความว่าอย่างไร?


คำตอบ:


139

หมายความว่าคุณควรใช้กรอบการบันทึกเช่น หรือ และแทนที่จะพิมพ์ข้อยกเว้นโดยตรง:

e.printStackTrace();

คุณควรบันทึกโดยใช้ API ของกรอบงานนี้:

log.error("Ops!", e);

เฟรมเวิร์กการบันทึกช่วยให้คุณมีความยืดหยุ่นอย่างมากเช่นคุณสามารถเลือกได้ว่าคุณต้องการเข้าสู่คอนโซลหรือไฟล์หรืออาจข้ามข้อความบางข้อความหากคุณพบว่าไม่เกี่ยวข้องอีกต่อไปในบางสภาพแวดล้อม


39

หากคุณเรียกprintStackTrace()หาข้อยกเว้นการติดตามจะถูกเขียนSystem.errและยากที่จะกำหนดเส้นทางไปที่อื่น (หรือกรอง) แทนที่จะทำเช่นนี้คุณควรใช้เฟรมเวิร์กการบันทึก (หรือ wrapper รอบ ๆ เฟรมเวิร์กการบันทึกหลาย ๆ เฟรมเช่น Apache Commons Logging) และบันทึกข้อยกเว้นโดยใช้เฟรมเวิร์กนั้น (เช่นlogger.error("some exception message", e))

การทำเช่นนั้นช่วยให้คุณ:

  • เขียนคำสั่งบันทึกไปยังตำแหน่งต่างๆพร้อมกันเช่นคอนโซลและไฟล์
  • กรองคำสั่งบันทึกตามความรุนแรง (ข้อผิดพลาดคำเตือนข้อมูลการดีบัก ฯลฯ ) และจุดเริ่มต้น (โดยปกติจะอิงตามแพ็กเกจหรือคลาส)
  • มีอิทธิพลต่อรูปแบบบันทึกโดยไม่ต้องเปลี่ยนรหัส
  • เป็นต้น

17

โปรแกรมคุณภาพการผลิตควรใช้หนึ่งในทางเลือกในการบันทึก (เช่น log4j, logback, java.util.logging) เพื่อรายงานข้อผิดพลาดและการวินิจฉัยอื่น ๆ สิ่งนี้มีข้อดีหลายประการ:

  • บันทึกข้อความไปยังตำแหน่งที่กำหนดได้
  • ผู้ใช้จะไม่เห็นข้อความเว้นแต่คุณจะกำหนดค่าการบันทึกเพื่อให้เขา / เธอทำ
  • คุณสามารถใช้คนตัดไม้และระดับการบันทึกที่แตกต่างกัน ฯลฯ เพื่อควบคุมว่าจะบันทึกการบันทึกน้อยหรือมากเพียงใด
  • คุณสามารถใช้รูปแบบ appender ต่างๆเพื่อควบคุมลักษณะการบันทึก
  • คุณสามารถเสียบเอาต์พุตการบันทึกเข้ากับเฟรมเวิร์กการตรวจสอบ / การบันทึกที่ใหญ่ขึ้นได้อย่างง่ายดาย
  • ทั้งหมดข้างต้นสามารถทำได้โดยไม่ต้องเปลี่ยนรหัสของคุณ กล่าวคือโดยการแก้ไขไฟล์กำหนดค่าการบันทึกของแอปพลิเคชันที่ปรับใช้

ในทางตรงกันข้ามถ้าคุณใช้ printStackTrace ผู้ปรับใช้ / ผู้ใช้ปลายทางจะมีการควบคุมเพียงเล็กน้อยและข้อความการบันทึกอาจสูญหายหรือแสดงต่อผู้ใช้ปลายทางในสถานการณ์ที่ไม่เหมาะสม (และไม่มีอะไรทำให้ผู้ใช้ขี้อายมากไปกว่าการติดตามสแต็กแบบสุ่ม)


6

ใน Simple e.printStackTrace () ไม่ใช่แนวทางปฏิบัติที่ดีเนื่องจากเพิ่งพิมพ์ stack trace เป็นข้อผิดพลาดมาตรฐาน ด้วยเหตุนี้คุณจึงไม่สามารถควบคุมได้ว่าผลลัพธ์นี้จะไปที่ใด


0

เกือบทุกเฟรมเวิร์กการบันทึกมีวิธีการที่เราสามารถส่งผ่านวัตถุที่สามารถโยนได้พร้อมกับข้อความ ชอบ:

public trace(Marker marker, String msg, Throwable t);

พวกเขาพิมพ์ stacktrace ของวัตถุที่สามารถโยนได้


สิ่งนี้ไม่ตอบคำถาม
Stephen C

-1

มาพูดคุยกันในแนวคิดของ บริษัท บันทึกช่วยให้คุณมีระดับที่ยืดหยุ่นได้ (ดูความแตกต่างระหว่าง logger.info และ logger.debug ) ผู้คนต่างต้องการเห็นระดับที่แตกต่างกันเช่น QA นักพัฒนานักธุรกิจ แต่ e.printStackTrace () จะพิมพ์ทุกอย่าง นอกจากนี้เช่นหากเรียกวิธีนี้อย่างสงบข้อผิดพลาดเดียวกันนี้อาจพิมพ์ได้หลายครั้ง จากนั้นคน Devops หรือ Tech-Ops ใน บริษัท ของคุณอาจบ้าคลั่งเพราะพวกเขาจะได้รับการแจ้งเตือนข้อผิดพลาดเดียวกัน ฉันคิดว่าการทดแทนที่ดีกว่าอาจเป็นได้log.error("errors happend in XXX", e) นอกจากนี้ยังจะพิมพ์ข้อมูลทั้งหมดซึ่งอ่านง่ายกว่า e.printStackTrace ()


-3

สาเหตุหลักคือ Proguard จะลบการโทรบันทึกออกจากการผลิต เนื่องจากด้วยการบันทึกหรือพิมพ์ StackTrace จึงเป็นไปได้ที่จะเห็นข้อมูลเหล่านี้ (ข้อมูลภายใน stack trace หรือ Log) ภายในโทรศัพท์ Android โดยตัวอย่างเช่นแอปพลิเคชัน Logcat Reader เพื่อให้เป็นการปฏิบัติที่ไม่ดีต่อความปลอดภัย. นอกจากนี้เราไม่สามารถเข้าถึงได้ในระหว่างการผลิตการลบออกจากการผลิตจะดีกว่า เนื่องจาก ProGuard ลบการเรียกบันทึกทั้งหมดที่ไม่ใช่ stackTrace ดังนั้นจึงเป็นการดีกว่าที่จะใช้บล็อก Log in catch และปล่อยให้นำออกจาก Production โดย Proguard

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.