Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
publish data in Graphite, if Graphite address configured
- Loading branch information
Showing
3 changed files
with
196 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
132 changes: 132 additions & 0 deletions
132
javamelody-core/src/main/java/net/bull/javamelody/Graphite.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
/* | ||
* Copyright 2008-2017 by Emeric Vernat | ||
* | ||
* This file is part of Java Melody. | ||
* | ||
* Licensed 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 net.bull.javamelody; | ||
|
||
import java.io.ByteArrayOutputStream; | ||
import java.io.IOException; | ||
import java.io.OutputStreamWriter; | ||
import java.io.Writer; | ||
import java.net.ConnectException; | ||
import java.net.InetAddress; | ||
import java.net.Socket; | ||
import java.net.UnknownHostException; | ||
import java.nio.charset.Charset; | ||
import java.text.DecimalFormat; | ||
import java.text.DecimalFormatSymbols; | ||
import java.util.Locale; | ||
|
||
import javax.net.SocketFactory; | ||
|
||
/** | ||
* Publish chart data to Graphite, http://graphiteapp.org/. | ||
* @author Emeric Vernat | ||
*/ | ||
class Graphite { | ||
private static final int DEFAULT_GRAPHITE_PORT = 2003; | ||
private static final char SEPARATOR = ' '; | ||
|
||
private final SocketFactory socketFactory; | ||
private final InetAddress address; | ||
private final int port; | ||
private final String prefix; | ||
|
||
private final DecimalFormat decimalFormat = new DecimalFormat("0.00", | ||
DecimalFormatSymbols.getInstance(Locale.US)); | ||
private final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); | ||
private final Writer bufferWriter; | ||
private long lastTime; | ||
private String lastTimestamp; | ||
|
||
Graphite(SocketFactory socketFactory, InetAddress address, int port, Charset charset, | ||
String prefix) { | ||
super(); | ||
assert socketFactory != null; | ||
assert address != null; | ||
assert charset != null; | ||
assert prefix != null; | ||
this.socketFactory = socketFactory; | ||
this.address = address; | ||
this.port = port; | ||
this.prefix = prefix; | ||
this.bufferWriter = new OutputStreamWriter(buffer, charset); | ||
} | ||
|
||
static Graphite getInstance() { | ||
final String graphiteAddress = Parameters.getParameter(Parameter.GRAPHITE_ADDRESS); | ||
if (graphiteAddress != null) { | ||
final String address; | ||
final int port; | ||
final int index = graphiteAddress.indexOf(':'); | ||
if (index != -1 && index < graphiteAddress.length()) { | ||
address = graphiteAddress.substring(0, index); | ||
port = Integer | ||
.parseInt(graphiteAddress.substring(index + 1, graphiteAddress.length())); | ||
} else { | ||
address = graphiteAddress; | ||
port = DEFAULT_GRAPHITE_PORT; | ||
} | ||
try { | ||
return new Graphite(SocketFactory.getDefault(), InetAddress.getByName(address), | ||
port, Charset.forName("UTF-8"), getDefaultPrefix()); | ||
} catch (final UnknownHostException e) { | ||
throw new IllegalArgumentException("Invalid host: " + address, e); | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
synchronized void addValue(String metric, double value) throws IOException { | ||
final long timeInSeconds = System.currentTimeMillis() / 1000; | ||
if (lastTime != timeInSeconds) { | ||
lastTimestamp = String.valueOf(timeInSeconds); | ||
lastTime = timeInSeconds; | ||
} | ||
bufferWriter.append(prefix).append('.').append(metric).append(' '); | ||
bufferWriter.append(decimalFormat.format(value)).append(' '); | ||
bufferWriter.append(lastTimestamp).append('\n'); | ||
} | ||
|
||
synchronized void send() throws IOException { | ||
try { | ||
bufferWriter.flush(); | ||
final Socket socket = createSocket(); | ||
try { | ||
buffer.writeTo(socket.getOutputStream()); | ||
} finally { | ||
socket.close(); | ||
} | ||
} catch (final ConnectException e) { | ||
throw new IOException("Error connecting to Graphite at " + address + ':' + port, e); | ||
} finally { | ||
// finally to be sure to not keep too much data in buffer | ||
// including when the socket can't connect | ||
buffer.reset(); | ||
} | ||
} | ||
|
||
private Socket createSocket() throws IOException { | ||
return socketFactory.createSocket(address, port); | ||
} | ||
|
||
private static String getDefaultPrefix() { | ||
final String defaultPrefix = "javamelody." + Parameters | ||
.getContextPath(Parameters.getServletContext()).replace("/", "").replace('.', '_') | ||
+ '.' + Parameters.getHostName().replace('.', '_'); | ||
return defaultPrefix.replace(SEPARATOR, '_'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters