我正在使用鑑別器登錄不同的文件。基於線程名稱。它通常提供良好的結果,但不包括那些與諸如名稱文件中的所有記錄儀的石英工作:我怎樣才能找到一個線程在java中運行的Quartz作業?
org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker - 1.登錄
我想有一個文件,這是石英作業的名稱(基於它的東西)能夠快速找到哪個文件包含作業的日誌。如果當前的線程與工作相關聯,請問石英有問題嗎?
感謝
我正在使用鑑別器登錄不同的文件。基於線程名稱。它通常提供良好的結果,但不包括那些與諸如名稱文件中的所有記錄儀的石英工作:我怎樣才能找到一個線程在java中運行的Quartz作業?
org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker - 1.登錄
我想有一個文件,這是石英作業的名稱(基於它的東西)能夠快速找到哪個文件包含作業的日誌。如果當前的線程與工作相關聯,請問石英有問題嗎?
感謝
最後,我用SLF4J手動表明MDC
在任務開始解決這個問題,我做
try {
MDC.put(MDC_KEY, getTaskName());
,並在年底
}
finally {
MDC.remove(MDC_KEY);
}
所以我只需要檢查MDC中的密鑰以瞭解我是否在任務內。
您的方法意味着您必須更改所有作業類的代碼(或從基礎作業類繼承)。但是,還有一種替代方法與代碼無法更改的作業兼容。
您可以創建在執行過程中更改線程名稱的作業監聽器(如下例所示)或設置MDC(如您的示例)並通過Scheduler.addJobListener()註冊或通過Spring進行配置。
public class RenameThreadWhenJobRunning extends JobListenerSupport {
/**
* Must provide two groups - for name and for number
*/
private String parsingPattern = "^(.+)_Worker-(\\d+)$";
/**
* {0} - Original full name (e.q. XXX_Worker-NN)
* {1} - XXX - original thread name
* {2} - NN - original worker number
* {3} - Job key (e.g. JobGroup.JobName)
* {4} - Job group
* {5} - Job name
*/
private String format = "{5}-Qz{2}";
public void setParsingPattern(String parsingPattern) {
this.parsingPattern = parsingPattern;
}
public void setFormat(String format) {
this.format = format;
}
@Override
public String getName() {
return RenameThreadWhenJobRunning.class.getSimpleName();
}
@Override
public void jobToBeExecuted(JobExecutionContext context) {
final String originalThreadName = currentThread().getName();
final Matcher matcher = Pattern.compile(parsingPattern).matcher(originalThreadName);
if (matcher.matches()) {
final JobKey key = context.getJobDetail().getKey();
currentThread().setName(format(format,
originalThreadName,
matcher.group(1),
matcher.group(2),
key.toString(),
key.getGroup(),
key.getName()
));
context.put(getOriginalThreadNameContextParameter(), originalThreadName);
}
}
@Override
public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
Object originalThreadName = context.get(getOriginalThreadNameContextParameter());
if (originalThreadName instanceof String) {
currentThread().setName((String)originalThreadName);
}
}
String getOriginalThreadNameContextParameter() {
return getName()+".originalThreadName";
}
}
如果我爲Thread和MessageFormat添加靜態導入,編譯如下: 'import static java.lang.Thread。*'and 'import static java.text.MessageFormat。*' – jerryb 2016-09-20 07:41:21
亞歷山大·帕夫洛夫的答案適合我(雖然我調整它使它成爲一個Groovy文件)。我所缺少的是將JobListener註冊到調度程序。
我將Alexander的RenameThreadWhenJobRunning類的單例實例註冊爲bean'renameThreadJobListener'。 'quartzScheduler'bean已經存在於我的應用程序上下文中。
由於我使用Grails,這裏是從我的resources.groovy塊,它可以移植到一個XML配置或基於註解的方法:
quartzSchedulerInitializer(QuartzSchedulerInitializer) { bean ->
bean.dependsOn = ['quartzScheduler', 'renameThreadJobListener'] as String[]
quartzScheduler = ref('quartzScheduler')
renameThreadJobListener = ref('renameThreadJobListener')
}
renameThreadJobListener(RenameThreadWhenJobRunning)
然後,我創建了下面的Groovy類:
import org.quartz.impl.matchers.EverythingMatcher
import org.springframework.beans.factory.InitializingBean
/**
* At application startup, register job listeners on the QuartzScheduler bean.
*/
class QuartzSchedulerInitializer implements InitializingBean {
def quartzScheduler
def renameThreadJobListener
@Override
void afterPropertiesSet() throws Exception {
def matcher = EverythingMatcher.allJobs()
quartzScheduler.listenerManager.addJobListener(renameThreadJobListener, matcher)
}
}
結果是我的工作線程名現在看起來像「com.example.MyJob-Qz1」!
MDC是一個很好的解決方案。謝謝。 – happyyangyuan 2015-06-01 06:35:50