<commit_before>﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;


namespace MAPE.Utils {
	public static class Logger {
		#region constants

		public const string SourceName = "MAPE";

		public const string SourceSwitchName = "MAPESwitch";

		public const int NoComponent = -1;

		#endregion


		#region data

		public static readonly SourceSwitch Switch = new SourceSwitch(SourceSwitchName);

		public static readonly TraceSource Source = new TraceSource(SourceName);

		#endregion


		#region data synchronized by classLocker

		private static readonly object classLocker = new object();

		private static SourceLevels sourceLevelsCache;

		private static TraceLevel logLevel;

		private static int nextComponentId = 0;

		private static bool loggingStopped = false;

		#endregion


		#region data synchronized by monitorsLocker

		private static readonly object monitorsLocker = new object();

		private static readonly List<ILogMonitor> monitors = new List<ILogMonitor>();

		#endregion


		#region data synchronized by deliveringLocker

		private static readonly object deliveringLocker = new object();

		private static readonly Queue<Log> logQueue = new Queue<Log>();

		private static Task deliveringTask = null;

		#endregion


		#region properties

		public static SourceLevels SourceLevels {
			get {
				return Logger.sourceLevelsCache;
			}
		}

		public static TraceLevel LogLevel {
			get {
				return Logger.logLevel;
			}
			set {
				lock (Logger.classLocker) {
					if (Logger.logLevel != value && Logger.loggingStopped == false) {
						Logger.logLevel = value;
						Logger.sourceLevelsCache = FromTraceLevel(Logger.Switch.Level, value);
						Logger.Switch.Level = Logger.sourceLevelsCache;
					}
				}
			}
		}

		#endregion


		#region creation

		static Logger() {
			// initialize members
			sourceLevelsCache = Switch.Level;

			// adjust Switch.Level to include Start/Stop event
			sourceLevelsCache |= SourceLevels.ActivityTracing;
			Switch.Level = sourceLevelsCache;

			logLevel = ToTraceLevel(Switch.Level);

			return;
		}

		#endregion


		#region methods - component id

		public static int AllocComponentId() {
			lock (classLocker) {
				if (Logger.nextComponentId == int.MaxValue) {
					throw new Exception("Internal resource overflow: no more component id to be allocated.");
				}
				return Logger.nextComponentId++;
			}
		}

		#endregion


		#region methods - log monitors

		public static void AddLogMonitor(ILogMonitor monitor) {
			// argument checks
			if (monitor == null) {<commit_msg>Fix the bug that the /LogLevel option does not work in CLI.<commit_after>﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;


namespace MAPE.Utils {
	public static class Logger {
		#region constants

		public const string SourceName = "MAPE";

		public const string SourceSwitchName = "MAPESwitch";

		public const int NoComponent = -1;

		#endregion


		#region data

		public static readonly TraceSource Source = new TraceSource(SourceName);

		#endregion


		#region data synchronized by classLocker

		private static readonly object classLocker = new object();

		private static SourceLevels sourceLevelsCache;

		private static TraceLevel logLevel;

		private static int nextComponentId = 0;

		private static bool loggingStopped = false;

		#endregion


		#region data synchronized by monitorsLocker

		private static readonly object monitorsLocker = new object();

		private static readonly List<ILogMonitor> monitors = new List<ILogMonitor>();

		#endregion


		#region data synchronized by deliveringLocker

		private static readonly object deliveringLocker = new object();

		private static readonly Queue<Log> logQueue = new Queue<Log>();

		private static Task deliveringTask = null;

		#endregion


		#region properties

		public static SourceLevels SourceLevels {
			get {
				return Logger.sourceLevelsCache;
			}
		}

		public static TraceLevel LogLevel {
			get {
				return Logger.logLevel;
			}
			set {
				lock (Logger.classLocker) {
					if (Logger.logLevel != value && Logger.loggingStopped == false) {
						Logger.logLevel = value;
						Logger.sourceLevelsCache = FromTraceLevel(Logger.Source.Switch.Level, value);
						Logger.Source.Switch.Level = Logger.sourceLevelsCache;
					}
				}
			}
		}

		#endregion


		#region creation

		static Logger() {
			// initialize members
			sourceLevelsCache = Logger.Source.Switch.Level;

			// adjust Switch.Level to include Start/Stop event
			sourceLevelsCache |= SourceLevels.ActivityTracing;
			Logger.Source.Switch.Level = sourceLevelsCache;

			logLevel = ToTraceLevel(Logger.Source.Switch.Level);

			return;
		}

		#endregion


		#region methods - component id

		public static int AllocComponentId() {
			lock (classLocker) {
				if (Logger.nextComponentId == int.MaxValue) {
					throw new Exception("Internal resource overflow: no more component id to be allocated.");
				}
				return Logger.nextComponentId++;
			}
		}

		#endregion


		#region methods - log monitors

		public static void AddLogMonitor(ILogMonitor monitor) {
			// argument checks
			if (monitor == null) {
{'fraction_non_alphanumeric': 0.07824427480916031, 'fraction_numerical': 0.0007633587786259542, 'mean_word_length': 3.6339522546419096, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5419504', 'n_tokens_mistral': 1752, 'n_tokens_neox': 1418, 'n_words': 450}