Evening,
I'm trying to create a timestamp for when an entity is added to my PriorityQueue using the following SimpleDate format: [yyyy/MM/dd - hh:mm:ss a] (Samples of results below)
Nano-second precision NOT 100% necessary
1: 2012/03/09 - 09:58:36 PM
Do you know how I can maintain an 'elapsed time' timestamp that shows when customers have been added to the PriorityQueue?
In the StackOverflow threads I've come across, most say to use System.nanoTime(); although I can't find resources online to implement this into a SimpleDateFormat. I have also consulted with colleagues.
Also, I apologize for not using syntax highlighting (if S.O supports it)
Code excerpt [unused methods omitted]:
<!-- language: java -->
package grocerystoresimulation;
/*****************************************************************************
* #import
*/
import java.util.PriorityQueue;
import java.util.Random;
import java.util.ArrayList;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
/************************************************************************************
public class GroceryStoreSimulation {
/************************************************************************************
* #fields
*/
private PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
private Random rand = new Random(); //instantiate new Random object
private Date date = new Date();
private DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd - hh:mm:ss a");
private ArrayList<String> timeStamp = new ArrayList<String>(); //store timestamps
private int customersServed; //# of customers served during simulation
/************************************************************************************
* #constuctor
*/
public GroceryStoreSimulation(){
System.out.println("Instantiated new GroceryStoreSimulation # ["
+ dateFormat.format(date) + "]\n" + insertDivider());
//Program body
while(true){
try{
Thread.sleep(generateWaitTime());
newCustomer(customersServed);
} catch(InterruptedException e){/*Catch 'em all*/}
}
}
/************************************************************************************
* #param String ID
*/
private void newCustomer(int ID){
System.out.println("Customer # " + customersServed + " added to queue. . .");
pq.offer(ID); //insert element into PriorityQueue
customersServed++;
assignArrivalTime(ID); //call assignArrivalTime() method
} //newCustomer()
/************************************************************************************
* #param String ID
*/
private void assignArrivalTime(int ID){
timeStamp.add(ID + ": " + dateFormat.format(date));
System.out.println(timeStamp.get(customersServed-1));
} //assignArrivalTime()
/************************************************************************************
* #return int
*/
private int generateWaitTime(){
//Local variables
int Low = 1000; //1000ms
int High = 4000; //4000ms
int waitTime = rand.nextInt(High-Low) + Low;
System.out.println("Delaying for: " + waitTime);
return waitTime;
}
//***********************************************************************************
private static String insertDivider(){
return ("******************************************************************");
}
//***********************************************************************************
} //GroceryStoreSimulation
Problem:
Timestamp does not update, only represents initial runtime (see below)
Delaying by 1-4 seconds w/Thread.sleep(xxx) (pseudo-randomly generated)
Problem may be in the assignArrivalTime() method
Output:
run:
Instantiated new GroceryStoreSimulation # [2012/03/09 - 09:58:36 PM]
******************************************************************
Delaying for: 1697
Customer # 0 added to queue. . .
0: 2012/03/09 - 09:58:36 PM
Delaying for: 3550
Customer # 1 added to queue. . .
1: 2012/03/09 - 09:58:36 PM
Delaying for: 2009
Customer # 2 added to queue. . .
2: 2012/03/09 - 09:58:36 PM
Delaying for: 1925
BUILD STOPPED (total time: 8 seconds)
Thank you for your assistance, I hope my question is clear enough & I`ve followed your formatting guidelines sufficiently.
You have to use a new instance of Date everytime to get most recent timestamp.
private void assignArrivalTime(int ID){
timeStamp.add(ID + ": " + dateFormat.format(date));
------------------------------------------------^^^^
Try replacing date by new Date() in above line.
Related
I have a csv file containing 24231 rows. I would like to apply LOOCV based on the project name instead of the observations of the whole dataset.
So if my dataset contains information for 15 projects, I would like to have the training set based on 14 projects and the test set based on the other project.
I was relying on weka's API, is there anything that automates this process?
For non-numeric attributes, Weka allows you to retrieve the unique values via Attribute.numValues() (how many are there) and Attribute.value(int) (the -th value).
package weka;
import weka.core.Attribute;
import weka.core.Instance;
import weka.core.Instances;
import weka.core.converters.ConverterUtils;
public class LOOByValue {
/**
* 1st arg: ARFF file to load
* 2nd arg: 0-based index in ARFF to use for class
* 3rd arg: 0-based index in ARFF to use for LOO
*
* #param args the command-line arguments
* #throws Exception if loading/processing of data fails
*/
public static void main(String[] args) throws Exception {
// load data
Instances full = ConverterUtils.DataSource.read(args[0]);
full.setClassIndex(Integer.parseInt(args[1]));
int looCol = Integer.parseInt(args[2]);
Attribute looAtt = full.attribute(looCol);
if (looAtt.isNumeric())
throw new IllegalStateException("Attribute cannot be numeric!");
// iterate unique values to create train/test splits
for (int i = 0; i < looAtt.numValues(); i++) {
String value = looAtt.value(i);
System.out.println("\n" + (i+1) + "/" + full.attribute(looCol).numValues() + ": " + value);
Instances train = new Instances(full, full.numInstances());
Instances test = new Instances(full, full.numInstances());
for (int n = 0; n < full.numInstances(); n++) {
Instance inst = full.instance(n);
if (inst.stringValue(looCol).equals(value))
test.add((Instance) inst.copy());
else
train.add((Instance) inst.copy());
}
train.compactify();
test.compactify();
// TODO do something with the data
System.out.println("train size: " + train.numInstances());
System.out.println("test size: " + test.numInstances());
}
}
}
With Weka's anneal UCI dataset and the surface-quality for leave-one-out, you can generate something like this:
1/5: ?
train size: 654
test size: 244
2/5: D
train size: 843
test size: 55
3/5: E
train size: 588
test size: 310
4/5: F
train size: 838
test size: 60
5/5: G
train size: 669
test size: 229
I would like to get the GMT [ Greenwich Mean Time ], and also I don't want to rely on my system date time for that. Basically, I want to use time sync server like in.pool.ntp.org [ India ] for GMT calculation, or may be I am going in wrong direction!
How to do this in java ?
Is there any java library to get time from Time server?
sp0d is not quite right:
timeInfo.getReturnTime(); // Returns time at which time message packet was received by local machine
So it just returns current system time, not the received one. See TimeInfo man page.
You should use
timeInfo.getMessage().getTransmitTimeStamp().getTime();
instead.
So the code block will be:
String TIME_SERVER = "time-a.nist.gov";
NTPUDPClient timeClient = new NTPUDPClient();
InetAddress inetAddress = InetAddress.getByName(TIME_SERVER);
TimeInfo timeInfo = timeClient.getTime(inetAddress);
long returnTime = timeInfo.getMessage().getTransmitTimeStamp().getTime();
Date time = new Date(returnTime);
Here is a code i found somewhere else.. and i am using it. Uses apache commons library.
List of time servers: NIST Internet Time Service
import java.net.InetAddress;
import java.util.Date;
import org.apache.commons.net.ntp.NTPUDPClient;
import org.apache.commons.net.ntp.TimeInfo;
public class TimeLookup {
public static void main() throws Exception {
String TIME_SERVER = "time-a.nist.gov";
NTPUDPClient timeClient = new NTPUDPClient();
InetAddress inetAddress = InetAddress.getByName(TIME_SERVER);
TimeInfo timeInfo = timeClient.getTime(inetAddress);
long returnTime = timeInfo.getReturnTime();
Date time = new Date(returnTime);
System.out.println("Time from " + TIME_SERVER + ": " + time);
}
}
Returns the output
Time from time-d.nist.gov: Sun Nov 25 06:04:34 IST 2012
I know this is an old question but I notice that all the answers are not correct or are complicated.
A nice and simple way to implement it is using Apache Commons Net library. This library will provide a NTPUDPClient class to manage connectionless NTP requests. This class will return a TimeInfo instance. This object should run the compute method to calculate the offset between your system's time and the NTP server's time. Lets try to implement it here
Add the Apache Commons Net library to your project.
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
Create a new instance of the NTPUDPClient class.
Setup the default timeout
Get the InetAddress of the NTP Server.
Call the NTPUDPClient.getTime() method to retrieve a TimeInfo instance with the time information from the specified server.
Call the computeDetails() method to compute and validate details of the NTP message packet.
Finally, get a NTP timestamp object based on a Java time by using this code TimeStamp.getNtpTime(currentTime + offset).getTime().
Here we have a basic implementation:
import java.net.InetAddress;
import java.util.Date;
import org.apache.commons.net.ntp.NTPUDPClient;
import org.apache.commons.net.ntp.TimeInfo;
public class NTPClient {
private static final String SERVER_NAME = "pool.ntp.org";
private volatile TimeInfo timeInfo;
private volatile Long offset;
public static void main() throws Exception {
NTPUDPClient client = new NTPUDPClient();
// We want to timeout if a response takes longer than 10 seconds
client.setDefaultTimeout(10_000);
InetAddress inetAddress = InetAddress.getByName(SERVER_NAME);
TimeInfo timeInfo = client.getTime(inetAddress);
timeInfo.computeDetails();
if (timeInfo.getOffset() != null) {
this.timeInfo = timeInfo;
this.offset = timeInfo.getOffset();
}
// This system NTP time
TimeStamp systemNtpTime = TimeStamp.getCurrentTime();
System.out.println("System time:\t" + systemNtpTime + " " + systemNtpTime.toDateString());
// Calculate the remote server NTP time
long currentTime = System.currentTimeMillis();
TimeStamp atomicNtpTime = TimeStamp.getNtpTime(currentTime + offset).getTime()
System.out.println("Atomic time:\t" + atomicNtpTime + " " + atomicNtpTime.toDateString());
}
public boolean isComputed()
{
return timeInfo != null && offset != null;
}
}
You will get something like that:
System time: dfaa2c15.2083126e Thu, Nov 29 2018 18:12:53.127
Atomic time: dfaa2c15.210624dd Thu, Nov 29 2018 18:12:53.129
This link demonstrates a java class called NtpMessage.java that you can paste into your program which will fetch the current time from an NTP server.
At the following link, Find the "Attachment" section near the bottom and download NtpMessage.java and SntpClient.java and paste it into your java application. It will do all the work and fetch you the time.
http://support.ntp.org/bin/view/Support/JavaSntpClient
Copy and paste of the code if it goes down:
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* This class represents a NTP message, as specified in RFC 2030. The message
* format is compatible with all versions of NTP and SNTP.
*
* This class does not support the optional authentication protocol, and
* ignores the key ID and message digest fields.
*
* For convenience, this class exposes message values as native Java types, not
* the NTP-specified data formats. For example, timestamps are
* stored as doubles (as opposed to the NTP unsigned 64-bit fixed point
* format).
*
* However, the contructor NtpMessage(byte[]) and the method toByteArray()
* allow the import and export of the raw NTP message format.
*
*
* Usage example
*
* // Send message
* DatagramSocket socket = new DatagramSocket();
* InetAddress address = InetAddress.getByName("ntp.cais.rnp.br");
* byte[] buf = new NtpMessage().toByteArray();
* DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 123);
* socket.send(packet);
*
* // Get response
* socket.receive(packet);
* System.out.println(msg.toString());
*
*
* This code is copyright (c) Adam Buckley 2004
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version. A HTML version of the GNU General Public License can be
* seen at http://www.gnu.org/licenses/gpl.html
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*
* Comments for member variables are taken from RFC2030 by David Mills,
* University of Delaware.
*
* Number format conversion code in NtpMessage(byte[] array) and toByteArray()
* inspired by http://www.pps.jussieu.fr/~jch/enseignement/reseaux/
* NTPMessage.java which is copyright (c) 2003 by Juliusz Chroboczek
*
* #author Adam Buckley
*/
public class NtpMessage
{
/**
* This is a two-bit code warning of an impending leap second to be
* inserted/deleted in the last minute of the current day. It's values
* may be as follows:
*
* Value Meaning
* ----- -------
* 0 no warning
* 1 last minute has 61 seconds
* 2 last minute has 59 seconds)
* 3 alarm condition (clock not synchronized)
*/
public byte leapIndicator = 0;
/**
* This value indicates the NTP/SNTP version number. The version number
* is 3 for Version 3 (IPv4 only) and 4 for Version 4 (IPv4, IPv6 and OSI).
* If necessary to distinguish between IPv4, IPv6 and OSI, the
* encapsulating context must be inspected.
*/
public byte version = 3;
/**
* This value indicates the mode, with values defined as follows:
*
* Mode Meaning
* ---- -------
* 0 reserved
* 1 symmetric active
* 2 symmetric passive
* 3 client
* 4 server
* 5 broadcast
* 6 reserved for NTP control message
* 7 reserved for private use
*
* In unicast and anycast modes, the client sets this field to 3 (client)
* in the request and the server sets it to 4 (server) in the reply. In
* multicast mode, the server sets this field to 5 (broadcast).
*/
public byte mode = 0;
/**
* This value indicates the stratum level of the local clock, with values
* defined as follows:
*
* Stratum Meaning
* ----------------------------------------------
* 0 unspecified or unavailable
* 1 primary reference (e.g., radio clock)
* 2-15 secondary reference (via NTP or SNTP)
* 16-255 reserved
*/
public short stratum = 0;
/**
* This value indicates the maximum interval between successive messages,
* in seconds to the nearest power of two. The values that can appear in
* this field presently range from 4 (16 s) to 14 (16284 s); however, most
* applications use only the sub-range 6 (64 s) to 10 (1024 s).
*/
public byte pollInterval = 0;
/**
* This value indicates the precision of the local clock, in seconds to
* the nearest power of two. The values that normally appear in this field
* range from -6 for mains-frequency clocks to -20 for microsecond clocks
* found in some workstations.
*/
public byte precision = 0;
/**
* This value indicates the total roundtrip delay to the primary reference
* source, in seconds. Note that this variable can take on both positive
* and negative values, depending on the relative time and frequency
* offsets. The values that normally appear in this field range from
* negative values of a few milliseconds to positive values of several
* hundred milliseconds.
*/
public double rootDelay = 0;
/**
* This value indicates the nominal error relative to the primary reference
* source, in seconds. The values that normally appear in this field
* range from 0 to several hundred milliseconds.
*/
public double rootDispersion = 0;
/**
* This is a 4-byte array identifying the particular reference source.
* In the case of NTP Version 3 or Version 4 stratum-0 (unspecified) or
* stratum-1 (primary) servers, this is a four-character ASCII string, left
* justified and zero padded to 32 bits. In NTP Version 3 secondary
* servers, this is the 32-bit IPv4 address of the reference source. In NTP
* Version 4 secondary servers, this is the low order 32 bits of the latest
* transmit timestamp of the reference source. NTP primary (stratum 1)
* servers should set this field to a code identifying the external
* reference source according to the following list. If the external
* reference is one of those listed, the associated code should be used.
* Codes for sources not listed can be contrived as appropriate.
*
* Code External Reference Source
* ---- -------------------------
* LOCL uncalibrated local clock used as a primary reference for
* a subnet without external means of synchronization
* PPS atomic clock or other pulse-per-second source
* individually calibrated to national standards
* ACTS NIST dialup modem service
* USNO USNO modem service
* PTB PTB (Germany) modem service
* TDF Allouis (France) Radio 164 kHz
* DCF Mainflingen (Germany) Radio 77.5 kHz
* MSF Rugby (UK) Radio 60 kHz
* WWV Ft. Collins (US) Radio 2.5, 5, 10, 15, 20 MHz
* WWVB Boulder (US) Radio 60 kHz
* WWVH Kaui Hawaii (US) Radio 2.5, 5, 10, 15 MHz
* CHU Ottawa (Canada) Radio 3330, 7335, 14670 kHz
* LORC LORAN-C radionavigation system
* OMEG OMEGA radionavigation system
* GPS Global Positioning Service
* GOES Geostationary Orbit Environment Satellite
*/
public byte[] referenceIdentifier = {0, 0, 0, 0};
/**
* This is the time at which the local clock was last set or corrected, in
* seconds since 00:00 1-Jan-1900.
*/
public double referenceTimestamp = 0;
/**
* This is the time at which the request departed the client for the
* server, in seconds since 00:00 1-Jan-1900.
*/
public double originateTimestamp = 0;
/**
* This is the time at which the request arrived at the server, in seconds
* since 00:00 1-Jan-1900.
*/
public double receiveTimestamp = 0;
/**
* This is the time at which the reply departed the server for the client,
* in seconds since 00:00 1-Jan-1900.
*/
public double transmitTimestamp = 0;
/**
* Constructs a new NtpMessage from an array of bytes.
*/
public NtpMessage(byte[] array)
{
// See the packet format diagram in RFC 2030 for details
leapIndicator = (byte) ((array[0] >> 6) & 0x3);
version = (byte) ((array[0] >> 3) & 0x7);
mode = (byte) (array[0] & 0x7);
stratum = unsignedByteToShort(array[1]);
pollInterval = array[2];
precision = array[3];
rootDelay = (array[4] * 256.0) +
unsignedByteToShort(array[5]) +
(unsignedByteToShort(array[6]) / 256.0) +
(unsignedByteToShort(array[7]) / 65536.0);
rootDispersion = (unsignedByteToShort(array[8]) * 256.0) +
unsignedByteToShort(array[9]) +
(unsignedByteToShort(array[10]) / 256.0) +
(unsignedByteToShort(array[11]) / 65536.0);
referenceIdentifier[0] = array[12];
referenceIdentifier[1] = array[13];
referenceIdentifier[2] = array[14];
referenceIdentifier[3] = array[15];
referenceTimestamp = decodeTimestamp(array, 16);
originateTimestamp = decodeTimestamp(array, 24);
receiveTimestamp = decodeTimestamp(array, 32);
transmitTimestamp = decodeTimestamp(array, 40);
}
/**
* Constructs a new NtpMessage in client -> server mode, and sets the
* transmit timestamp to the current time.
*/
public NtpMessage()
{
// Note that all the other member variables are already set with
// appropriate default values.
this.mode = 3;
this.transmitTimestamp = (System.currentTimeMillis()/1000.0) + 2208988800.0;
}
/**
* This method constructs the data bytes of a raw NTP packet.
*/
public byte[] toByteArray()
{
// All bytes are automatically set to 0
byte[] p = new byte[48];
p[0] = (byte) (leapIndicator << 6 | version << 3 | mode);
p[1] = (byte) stratum;
p[2] = (byte) pollInterval;
p[3] = (byte) precision;
// root delay is a signed 16.16-bit FP, in Java an int is 32-bits
int l = (int) (rootDelay * 65536.0);
p[4] = (byte) ((l >> 24) & 0xFF);
p[5] = (byte) ((l >> 16) & 0xFF);
p[6] = (byte) ((l >> 8) & 0xFF);
p[7] = (byte) (l & 0xFF);
// root dispersion is an unsigned 16.16-bit FP, in Java there are no
// unsigned primitive types, so we use a long which is 64-bits
long ul = (long) (rootDispersion * 65536.0);
p[8] = (byte) ((ul >> 24) & 0xFF);
p[9] = (byte) ((ul >> 16) & 0xFF);
p[10] = (byte) ((ul >> 8) & 0xFF);
p[11] = (byte) (ul & 0xFF);
p[12] = referenceIdentifier[0];
p[13] = referenceIdentifier[1];
p[14] = referenceIdentifier[2];
p[15] = referenceIdentifier[3];
encodeTimestamp(p, 16, referenceTimestamp);
encodeTimestamp(p, 24, originateTimestamp);
encodeTimestamp(p, 32, receiveTimestamp);
encodeTimestamp(p, 40, transmitTimestamp);
return p;
}
/**
* Returns a string representation of a NtpMessage
*/
public String toString()
{
String precisionStr =
new DecimalFormat("0.#E0").format(Math.pow(2, precision));
return "Leap indicator: " + leapIndicator + "\n" +
"Version: " + version + "\n" +
"Mode: " + mode + "\n" +
"Stratum: " + stratum + "\n" +
"Poll: " + pollInterval + "\n" +
"Precision: " + precision + " (" + precisionStr + " seconds)\n" +
"Root delay: " + new DecimalFormat("0.00").format(rootDelay*1000) + " ms\n" +
"Root dispersion: " + new DecimalFormat("0.00").format(rootDispersion*1000) + " ms\n" +
"Reference identifier: " + referenceIdentifierToString(referenceIdentifier, stratum, version) + "\n" +
"Reference timestamp: " + timestampToString(referenceTimestamp) + "\n" +
"Originate timestamp: " + timestampToString(originateTimestamp) + "\n" +
"Receive timestamp: " + timestampToString(receiveTimestamp) + "\n" +
"Transmit timestamp: " + timestampToString(transmitTimestamp);
}
/**
* Converts an unsigned byte to a short. By default, Java assumes that
* a byte is signed.
*/
public static short unsignedByteToShort(byte b)
{
if((b & 0x80)==0x80) return (short) (128 + (b & 0x7f));
else return (short) b;
}
/**
* Will read 8 bytes of a message beginning at <code>pointer</code>
* and return it as a double, according to the NTP 64-bit timestamp
* format.
*/
public static double decodeTimestamp(byte[] array, int pointer)
{
double r = 0.0;
for(int i=0; i<8; i++)
{
r += unsignedByteToShort(array[pointer+i]) * Math.pow(2, (3-i)*8);
}
return r;
}
/**
* Encodes a timestamp in the specified position in the message
*/
public static void encodeTimestamp(byte[] array, int pointer, double timestamp)
{
// Converts a double into a 64-bit fixed point
for(int i=0; i<8; i++)
{
// 2^24, 2^16, 2^8, .. 2^-32
double base = Math.pow(2, (3-i)*8);
// Capture byte value
array[pointer+i] = (byte) (timestamp / base);
// Subtract captured value from remaining total
timestamp = timestamp - (double) (unsignedByteToShort(array[pointer+i]) * base);
}
// From RFC 2030: It is advisable to fill the non-significant
// low order bits of the timestamp with a random, unbiased
// bitstring, both to avoid systematic roundoff errors and as
// a means of loop detection and replay detection.
array[7] = (byte) (Math.random()*255.0);
}
/**
* Returns a timestamp (number of seconds since 00:00 1-Jan-1900) as a
* formatted date/time string.
*/
public static String timestampToString(double timestamp)
{
if(timestamp==0) return "0";
// timestamp is relative to 1900, utc is used by Java and is relative
// to 1970
double utc = timestamp - (2208988800.0);
// milliseconds
long ms = (long) (utc * 1000.0);
// date/time
String date = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss").format(new Date(ms));
// fraction
double fraction = timestamp - ((long) timestamp);
String fractionSting = new DecimalFormat(".000000").format(fraction);
return date + fractionSting;
}
/**
* Returns a string representation of a reference identifier according
* to the rules set out in RFC 2030.
*/
public static String referenceIdentifierToString(byte[] ref, short stratum, byte version)
{
// From the RFC 2030:
// In the case of NTP Version 3 or Version 4 stratum-0 (unspecified)
// or stratum-1 (primary) servers, this is a four-character ASCII
// string, left justified and zero padded to 32 bits.
if(stratum==0 || stratum==1)
{
return new String(ref);
}
// In NTP Version 3 secondary servers, this is the 32-bit IPv4
// address of the reference source.
else if(version==3)
{
return unsignedByteToShort(ref[0]) + "." +
unsignedByteToShort(ref[1]) + "." +
unsignedByteToShort(ref[2]) + "." +
unsignedByteToShort(ref[3]);
}
// In NTP Version 4 secondary servers, this is the low order 32 bits
// of the latest transmit timestamp of the reference source.
else if(version==4)
{
return "" + ((unsignedByteToShort(ref[0]) / 256.0) +
(unsignedByteToShort(ref[1]) / 65536.0) +
(unsignedByteToShort(ref[2]) / 16777216.0) +
(unsignedByteToShort(ref[3]) / 4294967296.0));
}
return "";
}
}
The server time-a.nist.gov does not list the time port; you have to use correct server ntp.xs4all.nl for getting date and time from internet:
String TIME_SERVER = "ntp.xs4all.nl";
//... some other code
package modifiedlines;
import edu.nyu.cs.javagit.api.DotGit;
import edu.nyu.cs.javagit.api.JavaGitConfiguration;
import edu.nyu.cs.javagit.api.JavaGitException;
import edu.nyu.cs.javagit.api.WorkingTree;
import edu.nyu.cs.javagit.api.commands.GitLogResponse;
import edu.nyu.cs.javagit.api.commands.GitStatus;
import edu.nyu.cs.javagit.api.commands.GitStatusOptions;
import edu.nyu.cs.javagit.api.commands.GitStatusResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;
/**
*
* #
author aryan000
*/
public class UseGit {
private static File repositoryDirectory;
private static DotGit dotGit;
public static void main(String s[]) throws JavaGitException, IOException
{
File f = new File("C:\\Program Files\\Git\\bin\\git.exe");
if(!f.exists())
{
System.out.println("does not exist");
}
else
System.out.println("exists at " + f.getPath());
JavaGitConfiguration.setGitPath("C:\\Program Files\\Git\\bin");
System.out.println("Git version : " + JavaGitConfiguration.getGitVersion());
// repositoryDirectory = new File("/home/aryan000/Desktop/retrofit");
repositoryDirectory = new File("/home/aryan000/Desktop/changeprone/changeprone");
System.out.println("Git Repository Location : " + repositoryDirectory.getAbsolutePath());
//get the instance of the dotGit Object
dotGit = DotGit.getInstance(repositoryDirectory);
// System.out.println("checking what i have got ");
// GitLogResponse.CommitFile com ;
// com = (GitLogResponse.CommitFile) dotGit.getLog();
//
// System.out.println(com);
WorkingTree wt = dotGit.getWorkingTree();
File workingTreePath = wt.getPath();
GitStatus gitStatus = new GitStatus();
GitStatusResponse status = gitStatus.status(workingTreePath);
System.out.println("status is : " + status);
File anotherFileDir = new File("/home/aryan000/Desktop/retrofit/test.txt");
GitStatusOptions options = new GitStatusOptions();
options.setOptOnly(true);
status = gitStatus.status(workingTreePath);
System.out.println("status is : " + status);
System.out.println("----- Print log to see our commit -----");
for (GitLogResponse.Commit c : dotGit.getLog()) {
System.out.println("commit id is : " + c.getSha());
System.out.println(" commit message is : " + c.getMessage());
System.out.println(" author of the commit is : " + c.getAuthor());
System.out.println(" date modified is : " + c.getDateString());
System.out.println(" number of files changed is : " + c.getFiles());
List<GitLogResponse.CommitFile> store = c.getFiles();
if(store!=null)
System.out.println("the number of files changed is : " + store.size());
System.out.println("list of files changed is : " + c.getFilesChanged());
System.out.println("total number of additions : " + c.getLinesDeleted());
System.out.println("total number of merger : " + c.getMergeDetails());
}
// for(GitLogResponse.CommitFile c : dotGit.getLog())
}
}
Output is shown as :
Exception in thread "main" edu.nyu.cs.javagit.api.JavaGitException: 100002: Invalid path to git specified. { path=[C:\Program Files\Git\bin] }
at edu.nyu.cs.javagit.api.JavaGitConfiguration.setGitPath(JavaGitConfiguration.java:220)
at edu.nyu.cs.javagit.api.JavaGitConfiguration.setGitPath(JavaGitConfiguration.java:247)
at modifiedlines.UseGit.main(UseGit.java:40)
Caused by: edu.nyu.cs.javagit.api.JavaGitException: 100002: Invalid path to git specified.
at edu.nyu.cs.javagit.api.JavaGitConfiguration.determineGitVersion(JavaGitConfiguration.java:81)
at edu.nyu.cs.javagit.api.JavaGitConfiguration.setGitPath(JavaGitConfiguration.java:217)
... 2 more
Java Result: 1
My query is how to find git logs and the files changed due to a particular commit using a Java Program.
Can any 1 help me in this.
Please See : This code is working fine in Ubuntu i.e. no Path problem still I am unable to get the files changed during a commit. It is give me a List as a null.
This bug was opened a long time ago and just fixed it. Please give it a try , use master branch please, and let me know if it works for you.
I would like to perform a 10 fold cross validation on my data and I used the weka java programme. However, I encountered exception problems.
Here is the exceptions:
---Registering Weka Editors---
Trying to add database driver (JDBC): jdbc.idbDriver - Error, not in CLASSPATH?
Exception in thread "main" java.lang.IllegalArgumentException: No suitable converter found for ''!
at weka.core.converters.ConverterUtils$DataSource.<init>(ConverterUtils.java:137)
at weka.core.converters.ConverterUtils$DataSource.read(ConverterUtils.java:441)
at crossvalidationmultipleruns.CrossValidationMultipleRuns.main(CrossValidationMultipleRuns.java:45)
C:\Users\TomXavier\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 1 second)
Here is the programme I used:
import weka.core.Instances;
import weka.core.converters.ConverterUtils.DataSource;
import weka.core.Utils;
import weka.classifiers.Classifier;
import weka.classifiers.Evaluation;
import java.util.Random;
/**
* Performs a single run of cross-validation.
*
* Command-line parameters:
* <ul>
* <li>-t filename - the dataset to use</li>
* <li>-x int - the number of folds to use</li>
* <li>-s int - the seed for the random number generator</li>
* <li>-c int - the class index, "first" and "last" are accepted as well;
* "last" is used by default</li>
* <li>-W classifier - classname and options, enclosed by double quotes;
* the classifier to cross-validate</li>
* </ul>
*
* Example command-line:
* <pre>
* java CrossValidationSingleRun -t anneal.arff -c last -x 10 -s 1 -W "weka.classifiers.trees.J48 -C 0.25"
* </pre>
*
* #author FracPete (fracpete at waikato dot ac dot nz)
*/
public class CrossValidationSingleRun {
/**
* Performs the cross-validation. See Javadoc of class for information
* on command-line parameters.
*
* #param args the command-line parameters
* #throws Excecption if something goes wrong
*/
public static void main(String[] args) throws Exception {
// loads data and set class index
Instances data = DataSource.read(Utils.getOption("C:/Users/TomXavier/Documents/MATLAB/total_data.arff", args));
String clsIndex = Utils.getOption("first", args);
if (clsIndex.length() == 0)
clsIndex = "last";
if (clsIndex.equals("first"))
data.setClassIndex(0);
else if (clsIndex.equals("last"))
data.setClassIndex(data.numAttributes() - 1);
else
data.setClassIndex(Integer.parseInt(clsIndex) - 1);
// classifier
String[] tmpOptions;
String classname;
tmpOptions = Utils.splitOptions(Utils.getOption("weka.classifiers.trees.J48", args));
classname = tmpOptions[0];
tmpOptions[0] = "";
Classifier cls = (Classifier) Utils.forName(Classifier.class, classname, tmpOptions);
// other options
int seed = Integer.parseInt(Utils.getOption("1", args));
int folds = Integer.parseInt(Utils.getOption("10", args));
// randomize data
Random rand = new Random(seed);
Instances randData = new Instances(data);
randData.randomize(rand);
if (randData.classAttribute().isNominal())
randData.stratify(folds);
// perform cross-validation
Evaluation eval = new Evaluation(randData);
for (int n = 0; n < folds; n++) {
Instances train = randData.trainCV(folds, n);
Instances test = randData.testCV(folds, n);
// the above code is used by the StratifiedRemoveFolds filter, the
// code below by the Explorer/Experimenter:
// Instances train = randData.trainCV(folds, n, rand);
// build and evaluate classifier
Classifier clsCopy = Classifier.makeCopy(cls);
clsCopy.buildClassifier(train);
eval.evaluateModel(clsCopy, test);
}
// output evaluation
System.out.println();
System.out.println("=== Setup ===");
System.out.println("Classifier: " + cls.getClass().getName() + " " + Utils.joinOptions(cls.getOptions()));
System.out.println("Dataset: " + data.relationName());
System.out.println("Folds: " + folds);
System.out.println("Seed: " + seed);
System.out.println();
System.out.println(eval.toSummaryString("=== " + folds + "-fold Cross-validation ===", false));
}
}
Is there any solution for this problem?
Many thanks!
I have the following configuration:
log4j.appender.debug=org.apache.log4j.DailyRollingFileAppender
log4j.appender.debug.File=/path/to/log/log.txt
log4j.appender.debug.Append=true
log4j.appender.debug.DatePattern=.yyyy-MM-dd-HH-mm-ss
log4j.appender.debug.layout=org.apache.log4j.PatternLayout
log4j.appender.debug.layout.ConversionPattern=%n================================%n%d{yyyy-MM-dd-HH-mm-ss}%n%c%n%m %x%n--------------------------------%n
Currently, the files being rolled over is called:
log.txt.2014-10-26-14-12-33
Using the above DatePattern, however I would like the filename rolled over as:
2014-10-26-14-12-33.log.txt
However, it seems as if even when I remove the dot in the beginning and add it to the end, the filename is still appended to the beginning. So:
log4j.appender.debug.DatePattern=yyyy-MM-dd-HH-mm-ss'.ending'
Still logs as
log.txt.2014-10-26-14-12-33.ending
The reason is that I want the files to be easily sorted in the file explorer. I have several log files.
Is there a way to get log4j not to add the file name to the beginning of the rolled file?
Unfortunately no unless you customize and override the method called rollover in http://grepcode.com/file/repo1.maven.org/maven2/log4j/log4j/1.2.14/org/apache/log4j/DailyRollingFileAppender.java.
It does:
String datedFilename = fileName+sdf.format(now);
You will need to do:
String datedFilename = sdf.format(now).toString();
and use that class in your log4j xml.
Below one method has been added and called where normally schedueledTime is altered.
The method is moFilename which is called from two places, everything else is the same.
private String moFileName(File file, Date time) {
return file.getParent() + "/" + sdf.format(time) + "." + file.getName();
}
All code:
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.log4j;
import java.io.IOException;
import java.io.File;
import java.io.InterruptedIOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.Locale;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.LoggingEvent;
/**
DailyRollingFileAppender extends {#link FileAppender} so that the
underlying file is rolled over at a user chosen frequency.
DailyRollingFileAppender has been observed to exhibit
synchronization issues and data loss. The log4j extras
companion includes alternatives which should be considered
for new deployments and which are discussed in the documentation
for org.apache.log4j.rolling.RollingFileAppender.
<p>The rolling schedule is specified by the <b>DatePattern</b>
option. This pattern should follow the {#link SimpleDateFormat}
conventions. In particular, you <em>must</em> escape literal text
within a pair of single quotes. A formatted version of the date
pattern is used as the suffix for the rolled file name.
<p>For example, if the <b>File</b> option is set to
<code>/foo/bar.log</code> and the <b>DatePattern</b> set to
<code>'.'yyyy-MM-dd</code>, on 2001-02-16 at midnight, the logging
file <code>/foo/bar.log</code> will be copied to
<code>/foo/bar.log.2001-02-16</code> and logging for 2001-02-17
will continue in <code>/foo/bar.log</code> until it rolls over
the next day.
<p>Is is possible to specify monthly, weekly, half-daily, daily,
hourly, or minutely rollover schedules.
<p><table border="1" cellpadding="2">
<tr>
<th>DatePattern</th>
<th>Rollover schedule</th>
<th>Example</th>
<tr>
<td><code>'.'yyyy-MM</code>
<td>Rollover at the beginning of each month</td>
<td>At midnight of May 31st, 2002 <code>/foo/bar.log</code> will be
copied to <code>/foo/bar.log.2002-05</code>. Logging for the month
of June will be output to <code>/foo/bar.log</code> until it is
also rolled over the next month.
<tr>
<td><code>'.'yyyy-ww</code>
<td>Rollover at the first day of each week. The first day of the
week depends on the locale.</td>
<td>Assuming the first day of the week is Sunday, on Saturday
midnight, June 9th 2002, the file <i>/foo/bar.log</i> will be
copied to <i>/foo/bar.log.2002-23</i>. Logging for the 24th week
of 2002 will be output to <code>/foo/bar.log</code> until it is
rolled over the next week.
<tr>
<td><code>'.'yyyy-MM-dd</code>
<td>Rollover at midnight each day.</td>
<td>At midnight, on March 8th, 2002, <code>/foo/bar.log</code> will
be copied to <code>/foo/bar.log.2002-03-08</code>. Logging for the
9th day of March will be output to <code>/foo/bar.log</code> until
it is rolled over the next day.
<tr>
<td><code>'.'yyyy-MM-dd-a</code>
<td>Rollover at midnight and midday of each day.</td>
<td>At noon, on March 9th, 2002, <code>/foo/bar.log</code> will be
copied to <code>/foo/bar.log.2002-03-09-AM</code>. Logging for the
afternoon of the 9th will be output to <code>/foo/bar.log</code>
until it is rolled over at midnight.
<tr>
<td><code>'.'yyyy-MM-dd-HH</code>
<td>Rollover at the top of every hour.</td>
<td>At approximately 11:00.000 o'clock on March 9th, 2002,
<code>/foo/bar.log</code> will be copied to
<code>/foo/bar.log.2002-03-09-10</code>. Logging for the 11th hour
of the 9th of March will be output to <code>/foo/bar.log</code>
until it is rolled over at the beginning of the next hour.
<tr>
<td><code>'.'yyyy-MM-dd-HH-mm</code>
<td>Rollover at the beginning of every minute.</td>
<td>At approximately 11:23,000, on March 9th, 2001,
<code>/foo/bar.log</code> will be copied to
<code>/foo/bar.log.2001-03-09-10-22</code>. Logging for the minute
of 11:23 (9th of March) will be output to
<code>/foo/bar.log</code> until it is rolled over the next minute.
</table>
<p>Do not use the colon ":" character in anywhere in the
<b>DatePattern</b> option. The text before the colon is interpeted
as the protocol specificaion of a URL which is probably not what
you want.
#author Eirik Lygre
#author Ceki Gülcü*/
public class MoDailyRollingFileAppender extends FileAppender {
// The code assumes that the following constants are in a increasing
// sequence.
static final int TOP_OF_TROUBLE=-1;
static final int TOP_OF_MINUTE = 0;
static final int TOP_OF_HOUR = 1;
static final int HALF_DAY = 2;
static final int TOP_OF_DAY = 3;
static final int TOP_OF_WEEK = 4;
static final int TOP_OF_MONTH = 5;
/**
The date pattern. By default, the pattern is set to
"'.'yyyy-MM-dd" meaning daily rollover.
*/
private String datePattern = "'.'yyyy-MM-dd";
/**
The log file will be renamed to the value of the
scheduledFilename variable when the next interval is entered. For
example, if the rollover period is one hour, the log file will be
renamed to the value of "scheduledFilename" at the beginning of
the next hour.
The precise time when a rollover occurs depends on logging
activity.
*/
private String scheduledFilename;
/**
The next time we estimate a rollover should occur. */
private long nextCheck = System.currentTimeMillis () - 1;
Date now = new Date();
SimpleDateFormat sdf;
RollingCalendar rc = new RollingCalendar();
int checkPeriod = TOP_OF_TROUBLE;
// The gmtTimeZone is used only in computeCheckPeriod() method.
static final TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT");
/**
The default constructor does nothing. */
public MoDailyRollingFileAppender () {
}
/**
Instantiate a <code>DailyRollingFileAppender</code> and open the
file designated by <code>filename</code>. The opened filename will
become the ouput destination for this appender.
*/
public MoDailyRollingFileAppender (Layout layout, String filename,
String datePattern) throws IOException {
super(layout, filename, true);
this.datePattern = datePattern;
activateOptions();
}
/**
The <b>DatePattern</b> takes a string in the same format as
expected by {#link SimpleDateFormat}. This options determines the
rollover schedule.
*/
public void setDatePattern(String pattern) {
datePattern = pattern;
}
/** Returns the value of the <b>DatePattern</b> option. */
public String getDatePattern() {
return datePattern;
}
public void activateOptions() {
super.activateOptions();
if(datePattern != null && fileName != null) {
now.setTime(System.currentTimeMillis());
sdf = new SimpleDateFormat(datePattern);
int type = computeCheckPeriod();
printPeriodicity(type);
rc.setType(type);
File file = new File(fileName);
// Mo edit
scheduledFilename = moFileName(file, new Date(file.lastModified()));
} else {
LogLog.error("Either File or DatePattern options are not set for appender ["
+name+"].");
}
}
void printPeriodicity(int type) {
switch(type) {
case TOP_OF_MINUTE:
LogLog.debug("Appender ["+name+"] to be rolled every minute.");
break;
case TOP_OF_HOUR:
LogLog.debug("Appender ["+name
+"] to be rolled on top of every hour.");
break;
case HALF_DAY:
LogLog.debug("Appender ["+name
+"] to be rolled at midday and midnight.");
break;
case TOP_OF_DAY:
LogLog.debug("Appender ["+name
+"] to be rolled at midnight.");
break;
case TOP_OF_WEEK:
LogLog.debug("Appender ["+name
+"] to be rolled at start of week.");
break;
case TOP_OF_MONTH:
LogLog.debug("Appender ["+name
+"] to be rolled at start of every month.");
break;
default:
LogLog.warn("Unknown periodicity for appender ["+name+"].");
}
}
// This method computes the roll over period by looping over the
// periods, starting with the shortest, and stopping when the r0 is
// different from from r1, where r0 is the epoch formatted according
// the datePattern (supplied by the user) and r1 is the
// epoch+nextMillis(i) formatted according to datePattern. All date
// formatting is done in GMT and not local format because the test
// logic is based on comparisons relative to 1970-01-01 00:00:00
// GMT (the epoch).
int computeCheckPeriod() {
RollingCalendar rollingCalendar = new RollingCalendar(gmtTimeZone, Locale.getDefault());
// set sate to 1970-01-01 00:00:00 GMT
Date epoch = new Date(0);
if(datePattern != null) {
for(int i = TOP_OF_MINUTE; i <= TOP_OF_MONTH; i++) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(datePattern);
simpleDateFormat.setTimeZone(gmtTimeZone); // do all date formatting in GMT
String r0 = simpleDateFormat.format(epoch);
rollingCalendar.setType(i);
Date next = new Date(rollingCalendar.getNextCheckMillis(epoch));
String r1 = simpleDateFormat.format(next);
//System.out.println("Type = "+i+", r0 = "+r0+", r1 = "+r1);
if(r0 != null && r1 != null && !r0.equals(r1)) {
return i;
}
}
}
return TOP_OF_TROUBLE; // Deliberately head for trouble...
}
/**
Rollover the current file to a new file.
*/
void rollOver() throws IOException {
/* Compute filename, but only if datePattern is specified */
if (datePattern == null) {
errorHandler.error("Missing DatePattern option in rollOver().");
return;
}
File file = new File(fileName);
String datedFilename = moFileName(file, now);
// It is too early to roll over because we are still within the
// bounds of the current interval. Rollover will occur once the
// next interval is reached.
if (scheduledFilename.equals(datedFilename)) {
return;
}
// close current file, and rename it to datedFilename
this.closeFile();
File target = new File(scheduledFilename);
if (target.exists()) {
target.delete();
}
boolean result = file.renameTo(target);
if(result) {
LogLog.debug(fileName +" -> "+ scheduledFilename);
} else {
LogLog.error("Failed to rename ["+fileName+"] to ["+scheduledFilename+"].");
}
try {
// This will also close the file. This is OK since multiple
// close operations are safe.
this.setFile(fileName, true, this.bufferedIO, this.bufferSize);
}
catch(IOException e) {
errorHandler.error("setFile("+fileName+", true) call failed.");
}
scheduledFilename = datedFilename;
}
private String moFileName(File file, Date time) {
return file.getParent() + "/" + sdf.format(time) + "." + file.getName();
}
/**
* This method differentiates DailyRollingFileAppender from its
* super class.
*
* <p>Before actually logging, this method will check whether it is
* time to do a rollover. If it is, it will schedule the next
* rollover time and then rollover.
* */
protected void subAppend(LoggingEvent event) {
long n = System.currentTimeMillis();
if (n >= nextCheck) {
now.setTime(n);
nextCheck = rc.getNextCheckMillis(now);
try {
rollOver();
}
catch(IOException ioe) {
if (ioe instanceof InterruptedIOException) {
Thread.currentThread().interrupt();
}
LogLog.error("rollOver() failed.", ioe);
}
}
super.subAppend(event);
}
}
/**
* RollingCalendar is a helper class to DailyRollingFileAppender.
* Given a periodicity type and the current time, it computes the
* start of the next interval.
* */
class RollingCalendar extends GregorianCalendar {
private static final long serialVersionUID = -3560331770601814177L;
int type = DailyRollingFileAppender.TOP_OF_TROUBLE;
RollingCalendar() {
super();
}
RollingCalendar(TimeZone tz, Locale locale) {
super(tz, locale);
}
void setType(int type) {
this.type = type;
}
public long getNextCheckMillis(Date now) {
return getNextCheckDate(now).getTime();
}
public Date getNextCheckDate(Date now) {
this.setTime(now);
switch(type) {
case DailyRollingFileAppender.TOP_OF_MINUTE:
this.set(Calendar.SECOND, 0);
this.set(Calendar.MILLISECOND, 0);
this.add(Calendar.MINUTE, 1);
break;
case DailyRollingFileAppender.TOP_OF_HOUR:
this.set(Calendar.MINUTE, 0);
this.set(Calendar.SECOND, 0);
this.set(Calendar.MILLISECOND, 0);
this.add(Calendar.HOUR_OF_DAY, 1);
break;
case DailyRollingFileAppender.HALF_DAY:
this.set(Calendar.MINUTE, 0);
this.set(Calendar.SECOND, 0);
this.set(Calendar.MILLISECOND, 0);
int hour = get(Calendar.HOUR_OF_DAY);
if(hour < 12) {
this.set(Calendar.HOUR_OF_DAY, 12);
} else {
this.set(Calendar.HOUR_OF_DAY, 0);
this.add(Calendar.DAY_OF_MONTH, 1);
}
break;
case DailyRollingFileAppender.TOP_OF_DAY:
this.set(Calendar.HOUR_OF_DAY, 0);
this.set(Calendar.MINUTE, 0);
this.set(Calendar.SECOND, 0);
this.set(Calendar.MILLISECOND, 0);
this.add(Calendar.DATE, 1);
break;
case DailyRollingFileAppender.TOP_OF_WEEK:
this.set(Calendar.DAY_OF_WEEK, getFirstDayOfWeek());
this.set(Calendar.HOUR_OF_DAY, 0);
this.set(Calendar.MINUTE, 0);
this.set(Calendar.SECOND, 0);
this.set(Calendar.MILLISECOND, 0);
this.add(Calendar.WEEK_OF_YEAR, 1);
break;
case DailyRollingFileAppender.TOP_OF_MONTH:
this.set(Calendar.DATE, 1);
this.set(Calendar.HOUR_OF_DAY, 0);
this.set(Calendar.MINUTE, 0);
this.set(Calendar.SECOND, 0);
this.set(Calendar.MILLISECOND, 0);
this.add(Calendar.MONTH, 1);
break;
default:
throw new IllegalStateException("Unknown periodicity type.");
}
return getTime();
}
}
Config file is:
mo.log.pattern=%n================================%n%d{yyyy-MM-dd-HH-mm-ss}%n%c%n%m %x%n--------------------------------%n
mo.log.datepattern=yyyy-MM-dd-HH-mm-ss
log4j.appender.debug=org.apache.log4j.MoDailyRollingFileAppender
log4j.appender.debug.File=/path/to/Generated/Logs/debug.log
log4j.appender.debug.Append=true
log4j.appender.debug.DatePattern=${mo.log.datepattern}
log4j.appender.debug.layout=org.apache.log4j.PatternLayout
log4j.appender.debug.layout.ConversionPattern=${mo.log.pattern}