MatrixBerryCore
Log4jConfigurator.m
Go to the documentation of this file.
1 classdef Log4jConfigurator<handle
2 
3  properties (Constant,Abstract)
4  MASTER_LOG_FILE_NAME
5  CHILD_LOG_FILE_NAME_PREFIX
6  LOG_FILE_EXT
7  MAIN_LOG_FILE_PREFIX
8  SP_MAIN_LOG_FILE_NAME
9  SP_CUR_PROCESS_NAME
10  SP_LOG_DIR_WITH_SEP
11  SP_LOG_FILE_EXP
12  end
13  methods (Static,Access=protected)
14  function res = getSetConfStatus(varargin)
15  persistent isConfiguredPersistent;
16  if isempty(isConfiguredPersistent)
17  isConfiguredPersistent = false;
18  end
19  if ~isempty(varargin)
20  isConfiguredPersistent = varargin{1};
21  end
22  res = isConfiguredPersistent;
23  end
24  function res = getSetLockStatus(varargin)
25  persistent isLockedPersistent;
26  if isempty(isLockedPersistent)
27  isLockedPersistent = false;
28  end
29  if ~isempty(varargin)
30  isLockedPersistent = varargin{1};
31  end
32  res = isLockedPersistent;
33  end
34  function res = getSetLogPropStr(varargin)
35  import mxberry.core.throwerror;
36  persistent logPropStrPersistent;
37  if (nargin==0)
38  if isempty(logPropStrPersistent)
39  logPropStrPersistent = char(logPropStrPersistent);
40  end
41  else
42  inpLogPropStr=varargin{1};
43  if ~ischar(inpLogPropStr)
44  throwerror('wrongInput',['logPropStr is expected ',...
45  'to be a character array']);
46  end
47  logPropStrPersistent = varargin{1};
48  end
49  res=logPropStrPersistent;
50  end
51  end
52  methods (Static)
53  function res = isConfigured()
54  res = mxberry.log.log4j.Log4jConfigurator.getSetConfStatus();
55  end
56  function res = isLocked()
57  res = mxberry.log.log4j.Log4jConfigurator.getSetLockStatus();
58  end
59  function configureSimply(logLevel,varargin)
60  import org.apache.log4j.BasicConfigurator;
61  import org.apache.log4j.Level;
62  import org.apache.log4j.Logger;
63  import org.apache.log4j.spi.LoggerRepository;
64  import mxberry.log.log4j.Log4jConfigurator;
65  import mxberry.core.throwerror;
66  %
67  [~,prop]=mxberry.core.parseparams(varargin,[],0);
68  nProp=length(prop);
69  isLock = false;
70  for k=1:2:nProp-1
71  switch lower(prop{k})
72  case 'islockafterconfigure'
73  isLock=prop{k+1};
74  if ~isscalar(isLock) || ~islogical(isLock)
75  throwerror('wrongInput', ...
76  'Invalid size or tipe of %s', prop{k});
77  end
78  otherwise
79  throwerror('wrongInput', ...
80  'Property %s is not supported', prop{k});
81  end
82  end
83  %
85  logger=Logger.getLogger('mxberry.log.log4j.Log4jConfigurator');
86  logger.warn(['Attempt to change a locked Log4j configuration', sprintf('\n'), ...
87  mxberry.core.MExceptionUtils.meStack2String(...
88  dbstack('-completenames'),...
89  'useHyperlinks',false,'prefixStr',' ')]);
90  return;
91  end
92  %
93  %% set global INFO logging level
94  if nargin==0
95  logLevel='INFO';
96  end
97  BasicConfigurator.resetConfiguration();
98  BasicConfigurator.configure();
99  logger=Logger.getRootLogger();
100  repository=logger.getLoggerRepository();
101  repository.setThreshold(Level.(logLevel));
102  %
104  if isLock
106  end
107  end
108  function logger=getLogger(loggerName,isSuffix)
109  import org.apache.log4j.Logger;
110  if nargin<2
111  isSuffix=false;
112  end
113  if nargin==0||isSuffix
114  %
115  [methodName,className]=...
116  mxberry.core.getcallernameext(2);
117  % delete info on subfunctions
118  curInd=find(methodName=='/'|methodName=='\',1,'first');
119  if ~isempty(curInd)
120  methodName=methodName(1:curInd-1);
121  end
122  if ~isempty(className)
123  className=[className '.'];
124  end
125  if isSuffix
126  loggerName=[className methodName '.' loggerName];
127  else
128  loggerName=[className methodName];
129  end
130  end
131  logger=Logger.getLogger(loggerName);
132  end
133  function lockConfiguration()
134  mxberry.log.log4j.Log4jConfigurator.getSetLockStatus(true);
135  end
136  function unlockConfiguration()
137  mxberry.log.log4j.Log4jConfigurator.getSetLockStatus(false);
138  end
139  function res = getLastLogPropStr()
140  res = mxberry.log.log4j.Log4jConfigurator.getSetLogPropStr();
141  end
142  end
143  methods (Static,Abstract)
144  logFileName=getMainLogFileName()
145  configure(confSource)
146  end
147  methods (Access=protected)
148  function logFileName=getMainLogFileNameInternal(self)
149  logFileName=[self.getMainLogFilePathInternal,...
150  self.getShortMainLogFileNameInternal()];
151  end
152  function logFileName=getShortMainLogFileNameInternal(self)
153  import mxberry.log.log4j.Log4jConfigurator;
154  logFileName=[self.MAIN_LOG_FILE_PREFIX,...
155  self.getCurProcessNameInternal(),'.',...
156  self.LOG_FILE_EXT];
157  end
158  function processName=getCurProcessNameInternal(self)
159  import mxberry.log.log4j.Log4jConfigurator;
160  [~,SProp]=mxberry.pcalc.gettaskname();
161  if SProp.isMain
162  processName=self.MASTER_LOG_FILE_NAME;
163  else
164  curTaskName=['task',num2str(SProp.taskId)];
165  %
166  processName=[self.CHILD_LOG_FILE_NAME_PREFIX,'.',...
167  curTaskName];
168  end
169  end
170  function curPathWithFileSep=getMainLogFilePathInternal(self)
171  metaClass=metaclass(self);
172  curPathWithFileSep=[fileparts(which(metaClass.Name)),...
173  filesep,'Logs',filesep];
174  end
175  function configureInternal(self,logPropStr,varargin)
176  import org.apache.log4j.Logger;
177  import org.apache.log4j.PropertyConfigurator;
178  import mxberry.core.throwerror;
179  import mxberry.core.throwwarn;
180  %
181  [~,prop]=mxberry.core.parseparams(varargin,[],0);
182  nProp=length(prop);
183  isLock = false;
184  isLoggerSuffix = false;
185  for k=1:2:nProp-1
186  switch lower(prop{k})
187  case 'islockafterconfigure'
188  isLock=prop{k+1};
189  if ~isscalar(isLock) || ~islogical(isLock)
190  throwerror('wrongInput', ...
191  'Invalid size or tipe of %s', prop{k});
192  end
193  case 'loggersuffix'
194  isLoggerSuffix=true;
195  loggerSuffix=prop{k+1};
196  otherwise
197  throwerror('wrongInput', ...
198  'Property %s is not supported', prop{k});
199  end
200  end
201  metaClass=metaclass(self);
202  loggerName=metaClass.Name;
203  if isLoggerSuffix loggerName=[loggerName '.' loggerSuffix];
204  end
205  %
206  if self.isLocked()
207  logger=Logger.getLogger(loggerName);
208  logger.warn(...
209  ['Attempt to change a locked Log4j configuration',...
210  sprintf('\n'), ...
211  mxberry.core.MExceptionUtils.meStack2String(...
212  dbstack('-completenames'),...
213  'useHyperlinks',false,'prefixStr',' ')]);
214  return;
215  end
216  org.apache.log4j.BasicConfigurator.resetConfiguration();
217  %
218  if ~ischar(logPropStr)
219  throwerror('wrongInput',...
220  'configuration source should be a property string');
221  end
222  if isempty(logPropStr)
223  throwwarn('emptyConfStr',['configuration property ',...
224  'string is empty, doing nothing...']);
225  else
226  self.getSetLogPropStr(logPropStr);
227  logPropStr=java.lang.String(logPropStr);
228  %
229  java.lang.System.setProperty(...
230  self.SP_MAIN_LOG_FILE_NAME,...
231  self.getShortMainLogFileNameInternal);
232  %
233  logLocPath=self.getMainLogFilePathInternal();
234  %
235  if ~mxberry.io.isdir(logLocPath)
236  mxberry.io.mkdir(logLocPath);
237  end
238  %
239  java.lang.System.setProperty(...
240  self.SP_CUR_PROCESS_NAME,...
241  self.getCurProcessNameInternal);
242  java.lang.System.setProperty(...
243  self.SP_LOG_DIR_WITH_SEP,...
244  logLocPath);
245  %
246  java.lang.System.setProperty(...
247  self.SP_LOG_FILE_EXP,...
248  self.LOG_FILE_EXT);
249  %
250  confStream=java.io.ByteArrayInputStream(logPropStr.getBytes());
251  logProp=java.util.Properties();
252  logProp.load(confStream);
253  PropertyConfigurator.configure(logProp);
254  logger=Logger.getLogger(loggerName);
255  logger.info('Log4j is successfully configured');
256  %
257  self.getSetConfStatus(true);
258  if isLock
259  self.lockConfiguration();
260  end
261  end
262  end
263  end
264 end
LOG4JCONFIGURATOR simplifies log4j configuration, especially when Parallel Computing Toolbox is used...
function filesep()
function throwerror(in msgTag, in varargin)
THROWERROR works similarly to built-in ERROR function in case when there is no output arguments but s...
static function getSetConfStatus(in varargin)
function throwwarn(in msgTag, in varargin)
THROWWARN works similarly to built-in WARNING function in case when there is no output arguments but ...
function gettaskname()
GETTASKNAME returns task name and some additional properties.
function parseparams(in args, in propNameList, in nRegExpected, in nPropExpected)
PARSEPARAMS behaves exactly as a built-in Matlab function apart from the incorrect behavior of Matlab...