PageRenderTime 41ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/Kudu.Core/Deployment/XmlLogger.cs

https://github.com/moacap/kudu
C# | 144 lines | 122 code | 20 blank | 2 comment | 7 complexity | e45dc8272bb8eb331dabdb77de901b28 MD5 | raw file
Possible License(s): Apache-2.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO.Abstractions;
  4. using System.Linq;
  5. using System.Xml.Linq;
  6. using Kudu.Core.Infrastructure;
  7. namespace Kudu.Core.Deployment
  8. {
  9. public class XmlLogger : ILogger
  10. {
  11. private readonly string _path;
  12. private readonly IFileSystem _fileSystem;
  13. private readonly static object LogLock = new object();
  14. public XmlLogger(IFileSystem fileSystem, string path)
  15. {
  16. _fileSystem = fileSystem;
  17. _path = path;
  18. }
  19. public ILogger Log(string value, LogEntryType type)
  20. {
  21. value = XmlUtility.Sanitize(value);
  22. var xmlLogEntry = new XElement("entry",
  23. new XAttribute("time", DateTime.Now),
  24. new XAttribute("id", Guid.NewGuid()),
  25. new XAttribute("type", (int)type),
  26. new XElement("message", value));
  27. lock (LogLock)
  28. {
  29. XDocument document = GetDocument();
  30. document.Root.Add(xmlLogEntry);
  31. document.Save(_path);
  32. }
  33. return new InnerXmlLogger(this, xmlLogEntry);
  34. }
  35. public IEnumerable<LogEntry> GetLogEntries()
  36. {
  37. XDocument document;
  38. lock (LogLock)
  39. {
  40. document = GetDocument();
  41. }
  42. return from e in document.Root.Elements("entry")
  43. let time = DateTime.Parse(e.Attribute("time").Value)
  44. let type = (LogEntryType)Int32.Parse(e.Attribute("type").Value)
  45. select new LogEntry(time, e.Attribute("id").Value, e.Element("message").Value, type);
  46. }
  47. public IEnumerable<LogEntry> GetLogEntryDetails(string entryId)
  48. {
  49. XDocument document;
  50. lock (LogLock)
  51. {
  52. document = GetDocument();
  53. }
  54. return from e in document.Root.Elements("entry").Where(s => s.Attribute("id").Value == entryId).First().Elements("entry")
  55. let time = DateTime.Parse(e.Attribute("time").Value)
  56. let type = (LogEntryType)Int32.Parse(e.Attribute("type").Value)
  57. select new LogEntry(time, e.Attribute("id").Value, e.Element("message").Value, type);
  58. }
  59. public string GetFirstErrorEntryMessage()
  60. {
  61. XDocument document;
  62. lock (LogLock)
  63. {
  64. document = GetDocument();
  65. }
  66. var firstErrorEntry = document.Root.Elements("entry").First(s => s.Attribute("type").Value == ((int)(LogEntryType.Error)).ToString());
  67. if (firstErrorEntry != null)
  68. {
  69. return firstErrorEntry.Element("message").Value;
  70. }
  71. return "No error found in log.";
  72. }
  73. private XDocument GetDocument()
  74. {
  75. if (!_fileSystem.File.Exists(_path))
  76. {
  77. return new XDocument(new XElement("entries"));
  78. }
  79. XDocument document;
  80. using (var stream = _fileSystem.File.OpenRead(_path))
  81. {
  82. document = XDocument.Load(stream);
  83. }
  84. return document;
  85. }
  86. private class InnerXmlLogger : ILogger
  87. {
  88. private readonly XmlLogger _parent;
  89. private readonly XElement _element;
  90. public InnerXmlLogger(XmlLogger parent, XElement element)
  91. {
  92. _parent = parent;
  93. _element = element;
  94. }
  95. public ILogger Log(string value, LogEntryType type)
  96. {
  97. value = XmlUtility.Sanitize(value);
  98. var xmlLogEntry = new XElement("entry",
  99. new XAttribute("time", DateTime.Now),
  100. new XAttribute("id", Guid.NewGuid()),
  101. new XAttribute("type", (int)type),
  102. new XElement("message", value));
  103. lock (LogLock)
  104. {
  105. var document = _parent.GetDocument();
  106. var parentLogEntry = document.Root
  107. .Elements()
  108. .Where(s => s.Attribute("id").Value == _element.Attribute("id").Value)
  109. .First();
  110. parentLogEntry.Add(xmlLogEntry);
  111. // adjust log level of the parent log entry
  112. var parentLogEntryType = (LogEntryType)Enum.Parse(typeof(LogEntryType), parentLogEntry.Attribute("type").Value);
  113. if (type > parentLogEntryType)
  114. {
  115. parentLogEntry.Attribute("type").SetValue((int)type);
  116. }
  117. document.Save(_parent._path);
  118. }
  119. // Support a depthness of 2 for now.
  120. return this;
  121. }
  122. }
  123. }
  124. }