logger.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. # Copyright (C) 2012 Internet Systems Consortium.
  2. #
  3. # Permission to use, copy, modify, and distribute this software for any
  4. # purpose with or without fee is hereby granted, provided that the above
  5. # copyright notice and this permission notice appear in all copies.
  6. #
  7. # THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
  8. # DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
  9. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
  10. # INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
  11. # INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
  12. # FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  13. # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  14. # WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. """ This is a logging utility module for other modules of the ddns library
  16. package.
  17. """
  18. import isc.log
  19. # The logger for this package
  20. logger = isc.log.Logger('libddns')
  21. class ClientFormatter:
  22. """A utility class to convert a client address to string.
  23. This class is constructed with a Python standard socket address tuple.
  24. If it's 2-element tuple, it's assumed to be an IPv4 socket address
  25. and will be converted to the form of '<addr>:<port>(/key=<tsig-key>)'.
  26. If it's 4-element tuple, it's assumed to be an IPv6 socket address.
  27. and will be converted to the form of '[<addr>]:<por>(/key=<tsig-key>)'.
  28. The optional key=<tsig-key> will be added if a TSIG record is given
  29. on construction. tsig-key is the TSIG key name in that case.
  30. This class is designed to delay the conversion until it's explicitly
  31. requested, so the conversion doesn't happen if the corresponding log
  32. message is suppressed because of its log level (which is often the case
  33. for debug messages).
  34. Note: this optimization comes with the cost of instantiating the
  35. formatter object itself. It's not really clear which overhead is
  36. heavier, and we may conclude it's actually better to just generate
  37. the strings unconditionally. Alternatively, we can make the stored
  38. address of this object replaceable so that this object can be reused.
  39. Right now this is an open issue.
  40. """
  41. def __init__(self, addr, tsig_record=None):
  42. self.__addr = addr
  43. self.__tsig_record = tsig_record
  44. def __format_addr(self):
  45. if len(self.__addr) == 2:
  46. return self.__addr[0] + ':' + str(self.__addr[1])
  47. elif len(self.__addr) == 4:
  48. return '[' + self.__addr[0] + ']:' + str(self.__addr[1])
  49. return None
  50. def __str__(self):
  51. format = self.__format_addr()
  52. if format is not None and self.__tsig_record is not None:
  53. format += '/key=' + self.__tsig_record.get_name().to_text(True)
  54. return format
  55. class ZoneFormatter:
  56. """A utility class to convert zone name and class to string.
  57. This class is constructed with a name of a zone (isc.dns.Name object)
  58. and its RR class (isc.dns.RRClass object). Its text conversion method
  59. (__str__) converts them into a string in the form of
  60. '<zone name>/<zone class>' where the trailing dot of the zone name
  61. is omitted.
  62. If the given zone name on construction is None, it's assumed to be
  63. the zone isn't identified but needs to be somehow logged. The conversion
  64. method returns a special string to indicate this case.
  65. This class is designed to delay the conversion until it's explicitly
  66. requested, so the conversion doesn't happen if the corresponding log
  67. message is suppressed because of its log level (which is often the case
  68. for debug messages).
  69. See the note for the ClientFormatter class about overhead tradeoff.
  70. This class shares the same discussion.
  71. """
  72. def __init__(self, zname, zclass):
  73. self.__zname = zname
  74. self.__zclass = zclass
  75. def __str__(self):
  76. if self.__zname is None:
  77. return '(zone unknown/not determined)'
  78. return self.__zname.to_text(True) + '/' + self.__zclass.to_text()
  79. class RRsetFormatter:
  80. """A utility class to convert rrsets to a short descriptive string.
  81. This class is constructed with an rrset (isc.dns.RRset object).
  82. Its text conversion method (__str__) converts it into a string
  83. with only the name, class and type of the rrset.
  84. This is used in logging so that the RRset can be identified, without
  85. being completely printed, which would result in an unnecessary
  86. multi-line message.
  87. This class is designed to delay the conversion until it's explicitly
  88. requested, so the conversion doesn't happen if the corresponding log
  89. message is suppressed because of its log level.
  90. See the note for the ClientFormatter class about overhead tradeoff.
  91. This class shares the same discussion.
  92. """
  93. def __init__(self, rrset):
  94. self.__rrset = rrset
  95. def __str__(self):
  96. return self.__rrset.get_name().to_text() + " " +\
  97. self.__rrset.get_class().to_text() + " " +\
  98. self.__rrset.get_type().to_text()