Return-Path: X-Original-To: apmail-incubator-chukwa-user-archive@www.apache.org Delivered-To: apmail-incubator-chukwa-user-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 69BF3D3D0 for ; Tue, 10 Jul 2012 09:54:28 +0000 (UTC) Received: (qmail 14417 invoked by uid 500); 10 Jul 2012 09:54:28 -0000 Delivered-To: apmail-incubator-chukwa-user-archive@incubator.apache.org Received: (qmail 14325 invoked by uid 500); 10 Jul 2012 09:54:28 -0000 Mailing-List: contact chukwa-user-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: chukwa-user@incubator.apache.org Delivered-To: mailing list chukwa-user@incubator.apache.org Received: (qmail 14239 invoked by uid 99); 10 Jul 2012 09:54:27 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 10 Jul 2012 09:54:27 +0000 X-ASF-Spam-Status: No, hits=1.8 required=5.0 tests=FREEMAIL_ENVFROM_END_DIGIT,FSL_RCVD_USER,HTML_MESSAGE,RCVD_IN_DNSWL_LOW,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of ivytang0812@gmail.com designates 209.85.212.169 as permitted sender) Received: from [209.85.212.169] (HELO mail-wi0-f169.google.com) (209.85.212.169) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 10 Jul 2012 09:54:20 +0000 Received: by wibhm2 with SMTP id hm2so3080985wib.0 for ; Tue, 10 Jul 2012 02:54:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :content-type; bh=9gYS1KWthsarav4M/W2rtMIcfuVCvyPCA0lgiKTvrpY=; b=i9ahe68shA09DqVXkMxPdz3EG/JGgcSNoCSeXhmASIWtmrib2WJf7BK3HF9M6HUC9q xr6TkveXa6FaOHhyIhKKk1/XLX1b5inlZsJ3mMSTo0419YF/hmo0kqucrMqlrj1/FDzp Z4IbtpUc6vlkBCwLMbAg+ebmsyW3MVQ+0KntC+I4vuecIM1WVFHnQA2a5EUsZ/AWrtYz Dq3tGXVhxqTzX6SfvM8MaQWi8+eDSzIDpf/n3kahWACbUskvLl8+9Q+Db7BA567SWLL+ vpZ1zeK0hFAQHxxXNd4eVRfnH7pct9OVvGjSjhsM1SFKINsekUlDEVSV6VAarJ/qGfoi Ee+w== Received: by 10.216.133.200 with SMTP id q50mr3140257wei.166.1341914040299; Tue, 10 Jul 2012 02:54:00 -0700 (PDT) MIME-Version: 1.0 Received: by 10.194.42.101 with HTTP; Tue, 10 Jul 2012 02:53:40 -0700 (PDT) In-Reply-To: References: From: IvyTang Date: Tue, 10 Jul 2012 17:53:40 +0800 Message-ID: Subject: Re: Change the FileTailingAdaptor tailFile(),let it apply to the log4j rotated log files To: chukwa-user@incubator.apache.org Content-Type: multipart/alternative; boundary=0016e6de038cb0f18604c476b5e7 --0016e6de038cb0f18604c476b5e7 Content-Type: text/plain; charset=ISO-8859-1 Thanks for you reply! I will do this in JIRA issue. On Tue, Jul 10, 2012 at 4:36 PM, Ahmed Fathalla wrote: > Ivy, > > Thanks alot for your contributions! > > However, a better way to submit patches to Chukwa is: > > 1-Open a JIRA issue on > > https://issues.apache.org/jira/browse/CHUKWA > > I think you will need to register on JIRA first in order to create issues > > 2- Generate a .patch file using eclipse or command line tools, the .patch > file will be a single file with all the changes you have done. > > > 3- Using the "Submit Patch" option on the JIRA issue upload the file. Your > changes will be reviewed by a committer and committed if everything i okay. > > Thank you again for your interest in Chukwa and we really appreciate your > proactive approach in contributing back to the project! > > On Tue, Jul 10, 2012 at 10:04 AM, IvyTang wrote: > >> Our team has used chukwa *CharFileTailingAdaptorUTF8* to collect the >> log4j rotated log files for several months.It does help us to collect the >> logs from everywhere to our hadoop center. >> During the work , we met several problems . And i have raised them in >> this mail list , but i still haven't got a good solution. >> So we read the source code , and did some changes >> >> Our log files are generated by the log4j ,and the log4j appender is >> org.apache.log4j.DailyRollingFileAppender. >> If you use log4j to generate the rotated log ,may this mail will help you. >> >> These two problems are the causes why we have to modify the source code. >> >> 1. The mismatching checkpoint size and file size. >> >> I raised this problem in May 14 ,"the check point offset is bigger >> than the log file size". And Ariel Rabkin and Eric have answered my >> question , thanks for your replies. >> >> When chukwa starts, it will read the the check point file , let the >> size be the filereadoffset. The size in the checkpoint indicates how many >> bytes the adaptor has send . >> >> If the log source is stream or a file won't rotate , this size is >> right ,it indeed is the filereadoffset.But the file is rorated , the >> checkpoint size is often bigger than the file size ,and this will cause >> chukwa resend all the log file. >> >> So we add a "log.info("chunk seqID:"+c.getSeqID());" in >> ChukwaHttpSender:send. >> >> *for (Chunk c : toSend) { >> DataOutputBuffer b = new >> DataOutputBuffer(c.getSerializedSizeEstimate()); >> try { >> c.write(b); >> } catch (IOException err) { >> log.error("serialization threw IOException", err); >> } >> serializedEvents.add(b); >> // store a CLE for this chunk which we will use to ack this chunk >> to the >> // caller of send() >> // (e.g. the agent will use the list of CLE's for checkpointing) >> log.info("chunk seqID:"+c.getSeqID()); >> commitResults.add(new CommitListEntry(c.getInitiator(), >> c.getSeqID(), >> c.getSeqID() - c.getData().length)); >> }* >> * >> **The seqid is the offset of the send chunks in this log file.** >> * So when we need to restart the chukwa, we just need to stop the >> chukwa , change the size in checkpoint to the last chunk seqid in log and >> start chukwa. >> We also can directly apply the seqID to checkpoint size ,but we >> don't know if this will cause other problems. >> * >> >> *2.* *The method tailFile in FileTailingAdaptor is the core code of >> collecting the log. The code use the fileReadOffset , file length to detect >> the rotated file. >> *RandomAccessFile newReader = new RandomAccessFile(toWatch, "r"); >> * >> * len = reader.length();* >> * long newLength = newReader.length();* >> * if (newLength < len && fileReadOffset >= len) {* >> * if (reader != null) {* >> * reader.close();* >> * }* >> * * >> * reader = newReader;* >> * fileReadOffset = 0L;* >> * log.debug("Adaptor|"+ adaptorID + "| File size mismatched, >> rotating: "* >> * + toWatch.getAbsolutePath());* >> * } else {* >> * try {* >> * if (newReader != null) {* >> * newReader.close();* >> * }* >> * newReader =null;* >> * } catch (Throwable e) {* >> * // do nothing.* >> * }* >> * }* >> * >> * >> * *This arithmetic does work in most cases. But there is a case >> ,that when chukwa starts , the log file is 0 and it will be 0 untill it has >> been rotated. After it has been rotated ,becase its size is 0 ,this log >> will be removed. A new file has generated , and its size isn't 0. >> But the len is still 0 ,newLength is > 0.So this contition if >> (newLength < len && fileReadOffset >= len) will never be archived. The new >> log file will never be detected. >> >> So we changed the implemention of this method, we use timestamp >> to detect the new log file.The lastSlurpTime is the timestamp of the last >> slurp ,it is been declared and assigned in LWFTAdaptor . >> try { >> len = reader.length(); >> if(lastSlurpTime == 0){ >> lastSlurpTime = System.currentTimeMillis(); >> } >> if (offsetOfFirstByte > fileReadOffset) { >> // If the file rotated, the recorded >> offsetOfFirstByte is greater than >> // file size,reset the first byte position to >> beginning of the file. >> fileReadOffset = 0; >> offsetOfFirstByte = 0L; >> log.warn("offsetOfFirstByte>fileReadOffset, resetting >> offset to 0"); >> } >> if (len == fileReadOffset) { >> File fixedNameFile = new >> File(toWatch.getAbsolutePath()); >> long fixedNameLastModified = >> fixedNameFile.lastModified(); >> if (fixedNameLastModified > lastSlurpTime) { >> // If len == fileReadOffset,the file stops >> rolling log or the file has rotated. >> // But fixedNameLastModified > lastSlurpTime , >> this means after the last slurping,the file has been written . >> // so the file has been rotated. >> boolean hasLeftData = true; >> while(hasLeftData){// read the possiblly >> generated log >> hasLeftData = slurp(len, reader); >> } >> RandomAccessFile newReader = new >> RandomAccessFile(toWatch, "r"); >> if (reader != null) { >> reader.close(); >> } >> reader = newReader; >> fileReadOffset = 0L; >> len = reader.length(); >> log.debug("Adaptor|" + adaptorID + "| File size >> mismatched, rotating: " + >> toWatch.getAbsolutePath()); >> } >> hasMoreData = slurp(len, reader); >> } else if (len < fileReadOffset) { >> // file has rotated and no detection >> if (reader != null) { >> reader.close(); >> } >> reader = null; >> fileReadOffset = 0L; >> offsetOfFirstByte = 0L; >> hasMoreData = true; >> log.warn("Adaptor|" + adaptorID + "| file: " + >> toWatch.getPath() >> + ", has rotated and no detection - reset >> counters to 0L"); >> } else { >> hasMoreData = slurp(len, reader); >> } >> >> >> We hope these two changes will help the adaptor collect the rotated file >> more well. >> >> If these is anything wrong ,please let me know, >> >> Thanks! >> >> >> >> -- >> Best regards, >> >> Ivy Tang >> >> >> >> > > > -- > Ahmed Fathalla > -- Best regards, Ivy Tang --0016e6de038cb0f18604c476b5e7 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Thanks for you reply!

=A0I will do this in JIRA issue.
On Tue, Jul 10, 2012 at 4:36 PM, Ahmed Fat= halla <afathalla@gmail.com> wrote:
Ivy,

Tha= nks alot for your contributions! =A0

However, a be= tter way to submit patches to Chukwa is:

1-Open a JIRA issue on


<= div>I think you will need to register on JIRA first in order to create issu= es

2- Generate a .patch file using eclipse or command line tools, t= he .patch file will be a single file with all the changes you have done.


3- Using the "Submit Patch"= option on the JIRA issue upload the file. Your changes will be reviewed by= a committer and committed if everything i okay.

Thank you again for your interest in Chukwa and we real= ly appreciate your proactive approach in contributing back to the project!<= /div>

On Tue, Jul= 10, 2012 at 10:04 AM, IvyTang <ivytang0812@gmail.com> w= rote:
Our team has used chukwa CharFileTailingA= daptorUTF8 to collect the log4j rotated log files for several months.It= does help us to collect the logs from everywhere to our hadoop center.
During the work , we met several problems . And i have raised them in this = mail list , but i still haven't got a good solution.
So we=A0 read the source code , and did some changes

Our log files a= re generated by the log4j ,and the log4j appender is org.apache.log4j.Daily= RollingFileAppender.
If you use log4j to generate the rotated log ,may t= his mail will help you.

These two problems are the causes why we have to modify the source code= .

1. The mismatching checkpoint size and file size.

=A0=A0=A0= =A0 I raised this problem in May 14 ,"the check point offset is bigger= than the log file size". And Ariel Rabkin=A0 and Eric have answered m= y question , thanks for your replies.

=A0=A0=A0=A0 When chukwa starts, it will read the the check point file = , let the size be the filereadoffset. The size in the checkpoint indicates = how many bytes the adaptor has send .

=A0=A0=A0=A0 If the log source= is stream or a file won't rotate , this size is right ,it indeed is th= e filereadoffset.But the file is rorated , the checkpoint size is often big= ger than the file size ,and this will cause chukwa resend all the log file.=

=A0=A0=A0=A0 So we add a "log.info("chunk seqID:"+c.getSeqID());" in ChukwaH= ttpSender:send.

=A0=A0=A0=A0 for (Chunk c : toSend) {
=A0=A0= =A0=A0=A0 DataOutputBuffer b =3D new DataOutputBuffer(c.getSerializedSizeEs= timate());
=A0=A0=A0=A0=A0 try {
=A0=A0=A0=A0=A0=A0=A0 c.write(b);
=A0=A0=A0=A0= =A0 } catch (IOException err) {
=A0=A0=A0=A0=A0=A0=A0 log.error("se= rialization threw IOException", err);
=A0=A0=A0=A0=A0 }
=A0=A0= =A0=A0=A0 serializedEvents.add(b);
=A0=A0=A0=A0=A0 // store a CLE for th= is chunk which we will use to ack this chunk to the
=A0=A0=A0=A0=A0 // caller of send()
=A0=A0=A0=A0=A0 // (e.g. the agent w= ill use the list of CLE's for checkpointing)
=A0=A0=A0=A0=A0 log.info("chunk seqID:"= ;+c.getSeqID());
=A0=A0=A0=A0=A0 commitResults.add(new CommitListEntry(c= .getInitiator(), c.getSeqID(),
=A0=A0=A0=A0=A0=A0=A0=A0 c.getSeqID() - c.getData().length));
=A0=A0=A0 = }

=A0=A0=A0=A0
=A0=A0=A0
The seqid is the offset of th= e send chunks in this log file.
=A0=A0=A0
So when we need to = restart the chukwa, we just need to stop the chukwa , change the size in checkpoint to the last chunk seqid in log and start=20 chukwa. =A0=A0
=A0 =A0 =A0 We also can directly apply the seqID to checkpoint s= ize ,but we=20 don't know if this will cause other problems.


2. The method tailFile in FileTailingAdaptor is the core cod= e of collecting the log. The code use the=A0fileReadOffset , file length to= detect the rotated file.
=A0 =A0 =A0 =A0=A0RandomAccessFile newRead= er =3D new RandomAccessFile(toWatch, "r");
=A0 =A0 =A0 =A0 len =3D reader.length();
=A0 =A0 =A0 = =A0 long newLength =3D newReader.length();
=A0 =A0 =A0 =A0= if (newLength < len && fileReadOffset >=3D len) {
<= div>=A0 =A0 =A0 =A0 =A0 if (reader !=3D null) {
=A0 =A0 =A0 =A0 =A0 =A0 reader.close();
=A0 =A0 = =A0 =A0 =A0 }
=A0 =A0 =A0 =A0 =A0=A0
=A0 = =A0 =A0 =A0 =A0 reader =3D newReader;
=A0 =A0 =A0 =A0 =A0 = fileReadOffset =3D 0L;
=A0 =A0 =A0 =A0 =A0 log.debug("= ;Adaptor|"+ adaptorID + "| File size mismatched, rotating: "=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 + toWatch.getAbsolutePath());
=
=A0 =A0 =A0 =A0 } else {
=A0 =A0 =A0 =A0 =A0 try {=
=A0 =A0 =A0 =A0 =A0 =A0 if (newReader !=3D null) {
=A0 =A0 =A0 =A0 =A0 =A0 =A0 newReader.close();
=A0 =A0 =A0 =A0 =A0 =A0 }
=A0 =A0 =A0 =A0 =A0 =A0 = newReader =3Dnull;
=A0 =A0 =A0 =A0 =A0 } catch (Throwable = e) {
=A0 =A0 =A0 =A0 =A0 =A0 // do nothing.
= =A0 =A0 =A0 =A0 =A0 }
=A0 =A0 =A0 =A0 }

=A0 =A0 =A0This=A0arithmetic does work in= most cases. But there is a case ,that when chukwa starts , the log file is= 0 and it will be 0 untill it has been rotated. After it has been rotated ,= becase its size is 0 ,this log will be removed. A new file has generated , = and its size isn't 0.
=A0 =A0 =A0 But the len is still 0 ,newLength is > 0.So this contit= ion=A0=A0if (newLength < len && fileReadOffset >=3D len) =A0w= ill never be archived. The new log file will never be detected.
<= br>
=A0 =A0 =A0 =A0So we changed the implemention of this method, we use timest= amp to detect the new log file.The lastSlurpTime is the timestamp of the la= st slurp ,it is been declared and assigned in LWFTAdaptor . =A0=A0
=A0= =A0=A0=A0=A0=A0 try {
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 len =3D reader.length();
= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if(lastSlurpTime =3D=3D 0){=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 lastSlurpTime = =3D System.currentTimeMillis();
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0 }
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (offsetOfFirst= Byte > fileReadOffset) {
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 // If the file ro= tated, the recorded offsetOfFirstByte is greater than
=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 // file size,reset the first byte p= osition to beginning of the file.
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0 fileReadOffset =3D 0;
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 offsetOfFirstByte= =3D 0L;
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 log.w= arn("offsetOfFirstByte>fileReadOffset, resetting offset to 0")= ;
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 }=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0 if (len =3D=3D fileReadOffset) {
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 File fixedNameFil= e =3D new File(toWatch.getAbsolutePath());
=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 long fixedNameLastModified =3D fixedNameFile= .lastModified();
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0 if (fixedNameLastModified > lastSlurpTime) {
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 // If= len =3D=3D fileReadOffset,the file stops rolling log or the file has rotat= ed.
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0 // But fixedNameLastModified > lastSlurpTime , this means after the = last slurping,the file has been written .
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 // so= the file has been rotated.
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0 boolean hasLeftData =3D true;
=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 while(hasLeftData= ){// read the possiblly generated log
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 hasLeftData =3D slurp(len,= reader);
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 }
= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 Rando= mAccessFile newReader =3D new RandomAccessFile(toWatch, "r");
= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (r= eader !=3D null) {
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 reader.close();
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 }
= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 reade= r =3D newReader;
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0 fileReadOffset =3D 0L;
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 len =3D reader.length();
=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 log.debug(&quo= t;Adaptor|" + adaptorID + "| File size mismatched, rotating: &quo= t; + toWatch.getAbsolutePath());=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0 =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 }
=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 hasMoreData =3D slurp(len,= reader);
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 } else if (len &= lt; fileReadOffset) {
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0 // file has rotated and no detection
=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if (reader !=3D null) {
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 reade= r.close();
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 }=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 reader =3D null= ;
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 fileReadOffs= et =3D 0L;
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 off= setOfFirstByte =3D 0L;
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0=A0=A0 hasMoreData =3D true;
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 log.warn("Ad= aptor|" + adaptorID + "| file: " + toWatch.getPath()
=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0= =A0 + ", has rotated and no detection - reset counters to 0L");=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 } else {=A0=A0=A0=A0=A0=A0= =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 hasMoreData =3D s= lurp(len, reader);
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 }

We hope these two changes will help the adaptor collect the rotated f= ile more well.

If these is anything wrong ,please let me know,

Thanks!
=A0=A0=A0


--
Best re= gards,

Ivy Tang






--
Ahmed Fathalla



--
Best re= gards,

Ivy Tang



--0016e6de038cb0f18604c476b5e7--