Commit 0f47a8f8 authored by Pudding's avatar Pudding

initial commit

parents
package de.logger;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* FileWriter
*/
public class FileWriter implements Runnable {
private FileOutputStream fileOutputStream;
private final RingBuffer ringBuffer;
private boolean isRunning = false;
public FileWriter(final RingBuffer rb, final FileOutputStream fos) {
this.ringBuffer = rb;
this.fileOutputStream = fos;
}
public final void setFileOutputStream(final FileOutputStream fos) {
this.fileOutputStream = fos;
}
public final void abort() {
this.isRunning = false;
}
@Override
public void run(){
this.isRunning = true;
byte[] e;
while (this.isRunning) {
while ((e = this.ringBuffer.poll()) instanceof byte[]) {
try {
this.fileOutputStream.write(e);
this.fileOutputStream.flush();
} catch (IOException ex) {
throw new RuntimeException(ex.getMessage(), ex);
}
}
try {
this.wait();
} catch (InterruptedException ex) {
continue;
}
}
}
}
package de.logger;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
/**
* Logger
*/
public class Logger {
public final static String ERROR = "ERROR";
private Properties properties;
private final RingBuffer ringBuffer;
private final String lineSeparator = System.lineSeparator();
private ExecutorService threadPool;
private List<FileWriter> fileWriters = new ArrayList<FileWriter>();
private FileOutputStream fileOutputStream;
public Logger(Properties properties) throws Exception {
this.properties = properties;
this.ringBuffer = new RingBuffer(
Integer.parseInt(this.properties.getProperty("ringbuffer.size"))
);
int threadCount = Integer.parseInt(this.properties.getProperty("filewriter.threads"));
this.threadPool = Executors.newFixedThreadPool(threadCount);
this.fileOutputStream = new FileOutputStream(
this.properties.getProperty("log.file")
);
for (int x = 0; x < threadCount; x++) {
FileWriter fw = new FileWriter(ringBuffer, this.fileOutputStream);
this.fileWriters.add(fw);
this.threadPool.execute(fw);
}
}
public final void error(final byte[] message) {
if (this.properties.getProperty("log.level").equalsIgnoreCase(Logger.ERROR)) {
this.ringBuffer.add(message);
this.threadPool.notifyAll();
}
}
public void error(final String message) {
this.error(message.concat(this.lineSeparator).getBytes());
}
public final void close() throws Exception {
for (FileWriter fw : this.fileWriters) {
fw.abort();
}
this.threadPool.shutdown();
this.threadPool.awaitTermination(1, TimeUnit.DAYS);
this.fileOutputStream.close();
}
}
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package de.logger;
import java.util.Properties;
/**
*
* @author pudding
*/
public class Main {
public static void main(String[] args) throws Exception {
Properties p = new Properties();
p.setProperty("ringbuffer.size", "100000");
p.setProperty("filewriter.threads", "4");
p.setProperty("log.file", "test.log");
p.setProperty("log.level", "ERROR");
Logger logger = new Logger(p);
long start = System.currentTimeMillis();
for (int x = 0; x < 1000000; x++) {
logger.error(Integer.toString(x));
//Thread.sleep(1); // 0.1MS
}
logger.close();
System.out.println(System.currentTimeMillis() - start);
}
}
package de.logger;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReferenceArray;
/**
* RingBuffer
*/
public class RingBuffer implements Queue<byte[]> {
private final AtomicReferenceArray<byte[]> queue;
/**
*
*/
private final AtomicLong queueWritePosition = new AtomicLong();
private final AtomicLong queueReadPosition = new AtomicLong();
private final int size;
public RingBuffer(int size) {
this.size = size;
this.queue = new AtomicReferenceArray<>(size);
}
@Override
public boolean add(byte[] e) {
int pos = (int) (this.queueWritePosition.getAndIncrement() % this.size());
this.queue.set(pos, e);
return true;
}
@Override
public int size() {
return this.size;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public boolean contains(Object o) {
if (!(o instanceof byte[])) {
return false;
}
byte[] e = (byte[]) o;
for (int x = 0; x < this.size; x++) {
if (Arrays.equals(this.queue.get(x), e)) {
return true;
}
}
return false;
}
@Override
public boolean offer(byte[] e) {
return this.add(e);
}
@Override
public byte[] remove() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public byte[] poll() {
if (this.queueReadPosition.get() < this.queueWritePosition.get()) {
return this.queue.get((int) (this.queueReadPosition.getAndIncrement() % this.size()));
}
return null;
}
@Override
public byte[] element() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public byte[] peek() {
if (this.queueReadPosition.get() < this.queueWritePosition.get()) {
return this.queue.get((int) (this.queueReadPosition.get() % this.size()));
}
return null;
}
@Override
public Iterator<byte[]> iterator() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public Object[] toArray() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public <T> T[] toArray(T[] a) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public boolean remove(Object o) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public boolean containsAll(Collection<?> c) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public boolean addAll(Collection<? extends byte[]> c) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public boolean removeAll(Collection<?> c) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public boolean retainAll(Collection<?> c) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void clear() {
this.queueWritePosition.set(0L);
this.queueReadPosition.set(0L);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment