Skip to content

Live feature #142

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 16, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ open http://localhost:8080/seyren
* `MONGO_URL` - The Mongo [connection string](http://docs.mongodb.org/manual/reference/connection-string/). Default: `mongodb://localhost:27017/seyren`
* `SEYREN_URL` - The location of your Seyren instance. Default: `http://localhost:8080/seyren`

#### [Live feature](https://github.com/scobal/seyren/pull/142) (disabled by default)
* `GRAPHITE_CARBON_PICKLE_ENABLE` - Enable a TCP server to listen Carbon relay [pickle protocol](http://graphite.readthedocs.org/en/latest/feeding-carbon.html). Default: `false`
* `GRAPHITE_CARBON_PICKLE_PORT` - The TCP server port. Default: `2004`

#### SMTP
* `SMTP_HOST` - The smtp server to send email notifications from. Default: `localhost`
* `SMTP_PORT` - The smtp server port. Default: `25`
Expand Down
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
<org.mongodb.version>2.11.2</org.mongodb.version>
<org.slf4j.version>1.7.5</org.slf4j.version>
<org.springframework.version>3.2.4.RELEASE</org.springframework.version>
<org.python.version>2.5.3</org.python.version>
</properties>

<prerequisites>
Expand Down Expand Up @@ -370,6 +371,11 @@
<artifactId>spring-web</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
<version>${org.python.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public Response getChecks(Set<String> states, Boolean enabled) {
if (states != null && !states.isEmpty()) {
checks = checksStore.getChecksByState(states, enabled);
} else {
checks = checksStore.getChecks(enabled);
checks = checksStore.getChecks(enabled, null);
}
return Response.ok(checks).build();
}
Expand Down
4 changes: 4 additions & 0 deletions seyren-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
</dependency>
</dependencies>

</project>
22 changes: 18 additions & 4 deletions seyren-core/src/main/java/com/seyren/core/domain/Check.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public class Check {
private BigDecimal warn;
private BigDecimal error;
private boolean enabled;
private boolean live;
private AlertType state;
private DateTime lastCheck;
private List<Subscription> subscriptions = new ArrayList<Subscription>();
Expand Down Expand Up @@ -129,20 +130,33 @@ public Check withError(BigDecimal error) {
setError(error);
return this;
}

public boolean isEnabled() {
return enabled;
}

public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

public Check withEnabled(boolean enabled) {
setEnabled(enabled);
return this;
}


public boolean isLive() {
return live;
}

public void setLive(boolean live) {
this.live = live;
}

public Check withLive(boolean live) {
setLive(live);
return this;
}

public AlertType getState() {
return state;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* 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 com.seyren.core.service.checker;

import java.math.BigDecimal;
import java.util.Map;

import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import com.seyren.core.domain.Check;
import com.seyren.core.service.checker.TargetChecker;

public class NoopTargetCheck implements TargetChecker {
private BigDecimal value;

public NoopTargetCheck(BigDecimal value) {
this.value = value;
}

@Override
public Map<String, Optional<BigDecimal>> check(Check check) throws Exception {
return ImmutableMap.of(check.getTarget(), Optional.<BigDecimal>of(value));
}
}
80 changes: 80 additions & 0 deletions seyren-core/src/main/java/com/seyren/core/service/live/Metric.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* 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 com.seyren.core.service.live;

import java.math.BigDecimal;
import java.util.Date;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

import com.google.common.base.Objects;

public class Metric {
private String name;
private Date timestamp;
private BigDecimal value;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Date getTimestamp() {
return timestamp;
}

public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}

public BigDecimal getValue() {
return value;
}

public void setValue(BigDecimal value) {
this.value = value;
}

@Override
public boolean equals(Object obj) {
if(obj instanceof Metric) {
final Metric other = (Metric) obj;
return new EqualsBuilder()
.append(name, other.name)
.isEquals();
} else {
return false;
}
}

@Override
public int hashCode() {
return new HashCodeBuilder()
.append(name)
.toHashCode();
}

@Override
public String toString() {
return Objects.toStringHelper(this)
.add("name", getName())
.add("timestamp", getTimestamp())
.add("value", getValue())
.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* 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 com.seyren.core.service.live;

import java.util.Iterator;
import java.util.List;
import java.util.Set;

import com.google.common.base.Objects;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.seyren.core.domain.Check;
import com.seyren.core.service.schedule.CheckRunner;
import com.seyren.core.service.schedule.CheckRunnerFactory;
import com.seyren.core.store.ChecksStore;

public class MetricsTask implements Runnable {
private Set<Metric> metrics;
private ChecksStore checksStore;
private CheckRunnerFactory checkRunnerFactory;

public MetricsTask(Set<Metric> metrics, ChecksStore checksStore, CheckRunnerFactory checkRunnerFactory) {
this.metrics = metrics;
this.checksStore = checksStore;
this.checkRunnerFactory = checkRunnerFactory;
}

@Override
public void run() {
final List<Check> checks = checksStore.getChecks(true, true).getValues();
for (final Check check : checks) {
Iterator<Metric> metricByName = Iterables.filter(metrics, new FindByName(check.getName())).iterator();
if (metricByName.hasNext()) {
Metric found = metricByName.next();
CheckRunner runner = checkRunnerFactory.create(check, found.getValue());
runner.run();
}
}
}

private static class FindByName implements Predicate<Metric> {
private String name;

private FindByName(String name) {
this.name = name;
}

@Override
public boolean apply(Metric metric) {
return Objects.equal(metric.getName(), name);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/**
* 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 com.seyren.core.service.live.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
import javax.script.ScriptEngineManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.seyren.core.util.config.SeyrenConfig;

/**
* ServerSocket listening Carbon Relay Pickle protocol (aka python serialization).
*/
@Named
public class CarbonPickleListener {
private static final Logger LOGGER = LoggerFactory.getLogger(CarbonPickleListener.class);

private SeyrenConfig seyrenConfig;
private PickleHandlerFactory pickleHandlerFactory;

@Inject
public CarbonPickleListener(SeyrenConfig seyrenConfig, PickleHandlerFactory pickleHandlerFactory) {
this.seyrenConfig = seyrenConfig;
this.pickleHandlerFactory = pickleHandlerFactory;
}

@PostConstruct
public void initialize() throws Exception {
if (seyrenConfig.getGraphiteCarbonPickleEnable()) {
new ScriptEngineManager().getEngineByName("python");
bootstrap();
} else {
LOGGER.info("Carbon Pickle Listener disabled.");
}
}

public void bootstrap() throws Exception {
LOGGER.info("Carbon Pickle Listener enabled.");
Thread thread = new Thread("Carbon Pickle Listener") {
@Override
public void run() {
ServerSocket serverSocket = null;
ExecutorService tasks = Executors.newFixedThreadPool(2);
try {
serverSocket = new ServerSocket(seyrenConfig.getGraphiteCarbonPicklePort());
serverSocket.setReuseAddress(true);
serverSocket.setReceiveBufferSize(1024 * 1024);

while (true) {
LOGGER.debug("Accepting...");
Socket socket = serverSocket.accept();
socket.setKeepAlive(true);
socket.setTcpNoDelay(true);
socket.setReceiveBufferSize(1024 * 1024);
tasks.execute(pickleHandlerFactory.create(socket));
}
} catch (IOException e) {
LOGGER.warn("Error: ", e);
} finally {
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
}
}
}
}
};
thread.start();
}

}
Loading