kris/log_flag_ui
a master
4 anni fa
@@ -10,9 +10,13 @@ import lombok.NonNull; | |||||
import org.glassfish.jersey.server.ContainerRequest; | import org.glassfish.jersey.server.ContainerRequest; | ||||
import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
import javax.annotation.Nullable; | |||||
import javax.ws.rs.*; | import javax.ws.rs.*; | ||||
import javax.ws.rs.core.Context; | import javax.ws.rs.core.Context; | ||||
import javax.ws.rs.core.Response; | import javax.ws.rs.core.Response; | ||||
import java.util.HashMap; | |||||
import java.util.Optional; | |||||
import java.util.concurrent.TimeUnit; | |||||
import static bubble.ApiConstants.*; | import static bubble.ApiConstants.*; | ||||
import static org.cobbzilla.util.http.HttpContentTypes.APPLICATION_JSON; | import static org.cobbzilla.util.http.HttpContentTypes.APPLICATION_JSON; | ||||
@@ -33,17 +37,26 @@ public class LogsResource { | |||||
@GET @Path(EP_STATUS) | @GET @Path(EP_STATUS) | ||||
@NonNull public Response getLoggingStatus(@NonNull @Context final ContainerRequest ctx) { | @NonNull public Response getLoggingStatus(@NonNull @Context final ContainerRequest ctx) { | ||||
return ok(selfNodeService.getLogFlag()); | |||||
final var flag = new HashMap<String, Object>(2); | |||||
flag.put("flag", selfNodeService.getLogFlag()); | |||||
flag.put("expireAt", selfNodeService.getLogFlagExpirationTime().orElse(null)); | |||||
return ok(flag); | |||||
} | } | ||||
@POST @Path(EP_START) | @POST @Path(EP_START) | ||||
@NonNull public Response startLogging(@NonNull @Context final ContainerRequest ctx) { return setLogFlag(true); } | |||||
@NonNull public Response startLogging(@NonNull @Context final ContainerRequest ctx, | |||||
@Nullable @QueryParam("ttlDays") final Byte ttlDays) { | |||||
return setLogFlag(true, Optional.ofNullable(ttlDays)); | |||||
} | |||||
@POST @Path(EP_STOP) | @POST @Path(EP_STOP) | ||||
@NonNull public Response stopLogging(@NonNull @Context final ContainerRequest ctx) { return setLogFlag(false); } | |||||
@NonNull public Response stopLogging(@NonNull @Context final ContainerRequest ctx) { | |||||
return setLogFlag(false, Optional.empty()); | |||||
} | |||||
@NonNull private Response setLogFlag(final boolean b) { | |||||
@NonNull private Response setLogFlag(final boolean b, @NonNull final Optional<Byte> ttlInDays) { | |||||
if (!account.admin()) throw forbiddenEx(); // caller must be admin | if (!account.admin()) throw forbiddenEx(); // caller must be admin | ||||
selfNodeService.setLogFlag(b); | |||||
selfNodeService.setLogFlag(b, ttlInDays.map(days -> (int) TimeUnit.DAYS.toSeconds(days))); | |||||
return ok(); | return ok(); | ||||
} | } | ||||
} | } |
@@ -7,6 +7,9 @@ package bubble.service.boot; | |||||
import bubble.model.bill.BubblePlan; | import bubble.model.bill.BubblePlan; | ||||
import bubble.model.cloud.BubbleNetwork; | import bubble.model.cloud.BubbleNetwork; | ||||
import bubble.model.cloud.BubbleNode; | import bubble.model.cloud.BubbleNode; | ||||
import lombok.NonNull; | |||||
import java.util.Optional; | |||||
public interface SelfNodeService { | public interface SelfNodeService { | ||||
@@ -24,6 +27,13 @@ public interface SelfNodeService { | |||||
BubblePlan getThisPlan(); | BubblePlan getThisPlan(); | ||||
Boolean getLogFlag(); | |||||
void setLogFlag(final boolean logFlag); | |||||
boolean getLogFlag(); | |||||
/** | |||||
* @return Empty if TTL for log flag is a special one (less than 0), else timestamp (milliseconds) when log flag | |||||
* will be expired (to be precise, a very close time after the real expiration time as some time is spent | |||||
* for processing here). | |||||
*/ | |||||
@NonNull Optional<Long> getLogFlagExpirationTime(); | |||||
void setLogFlag(final boolean logFlag, @NonNull final Optional<Integer> ttlInSeconds); | |||||
} | } |
@@ -41,6 +41,7 @@ import org.springframework.stereotype.Service; | |||||
import java.io.File; | import java.io.File; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Optional; | |||||
import java.util.concurrent.atomic.AtomicBoolean; | import java.util.concurrent.atomic.AtomicBoolean; | ||||
import java.util.concurrent.atomic.AtomicReference; | import java.util.concurrent.atomic.AtomicReference; | ||||
@@ -52,8 +53,7 @@ import static bubble.server.BubbleServer.isRestoreMode; | |||||
import static java.util.concurrent.TimeUnit.DAYS; | import static java.util.concurrent.TimeUnit.DAYS; | ||||
import static java.util.concurrent.TimeUnit.MINUTES; | import static java.util.concurrent.TimeUnit.MINUTES; | ||||
import static java.util.function.Predicate.not; | import static java.util.function.Predicate.not; | ||||
import static org.cobbzilla.util.daemon.ZillaRuntime.background; | |||||
import static org.cobbzilla.util.daemon.ZillaRuntime.die; | |||||
import static org.cobbzilla.util.daemon.ZillaRuntime.*; | |||||
import static org.cobbzilla.util.io.FileUtil.abs; | import static org.cobbzilla.util.io.FileUtil.abs; | ||||
import static org.cobbzilla.util.io.FileUtil.toFileOrDie; | import static org.cobbzilla.util.io.FileUtil.toFileOrDie; | ||||
import static org.cobbzilla.util.json.JsonUtil.*; | import static org.cobbzilla.util.json.JsonUtil.*; | ||||
@@ -72,8 +72,8 @@ public class StandardSelfNodeService implements SelfNodeService { | |||||
public static final long MIN_SAGE_KEY_TTL = MINUTES.toMillis(5); | public static final long MIN_SAGE_KEY_TTL = MINUTES.toMillis(5); | ||||
private static final String REDIS_LOG_FLAG_KEY = "bubble_server_logs_enabled"; | private static final String REDIS_LOG_FLAG_KEY = "bubble_server_logs_enabled"; | ||||
private static final long TTL_LOG_FLAG_NODE = DAYS.toSeconds(7); | |||||
private static final long TTL_LOG_FLAG_SAGE = DAYS.toSeconds(30); | |||||
private static final int TTL_LOG_FLAG_NODE = (int) DAYS.toSeconds(7); | |||||
private static final int TTL_LOG_FLAG_SAGE = (int) DAYS.toSeconds(30); | |||||
@Autowired private BubbleNodeDAO nodeDAO; | @Autowired private BubbleNodeDAO nodeDAO; | ||||
@Autowired private BubbleNodeKeyDAO nodeKeyDAO; | @Autowired private BubbleNodeKeyDAO nodeKeyDAO; | ||||
@@ -442,16 +442,22 @@ public class StandardSelfNodeService implements SelfNodeService { | |||||
} | } | ||||
@Override | @Override | ||||
public Boolean getLogFlag() { | |||||
if (!getNodeConfig().exists(REDIS_LOG_FLAG_KEY)) return false; | |||||
return Boolean.valueOf(getNodeConfig().get_plaintext(REDIS_LOG_FLAG_KEY)); | |||||
public boolean getLogFlag() { | |||||
var flagStr = getNodeConfig().get_plaintext(REDIS_LOG_FLAG_KEY); | |||||
return empty(flagStr) ? false : Boolean.valueOf(flagStr); | |||||
} | } | ||||
@Override | @Override | ||||
public void setLogFlag(final boolean logFlag) { | |||||
@NonNull public Optional<Long> getLogFlagExpirationTime() { | |||||
var ttl = getNodeConfig().get_ttl(REDIS_LOG_FLAG_KEY); | |||||
return ttl < 0 ? Optional.empty() : Optional.of(now() + ttl * 1000); | |||||
} | |||||
@Override | |||||
public void setLogFlag(final boolean logFlag, @NonNull final Optional<Integer> ttlInSeconds) { | |||||
if (logFlag) { | if (logFlag) { | ||||
getNodeConfig().set_plaintext(REDIS_LOG_FLAG_KEY, "true", EX, | getNodeConfig().set_plaintext(REDIS_LOG_FLAG_KEY, "true", EX, | ||||
isSelfSage() ? TTL_LOG_FLAG_SAGE : TTL_LOG_FLAG_NODE); | |||||
ttlInSeconds.orElse(isSelfSage() ? TTL_LOG_FLAG_SAGE : TTL_LOG_FLAG_NODE)); | |||||
} else { | } else { | ||||
// just (try to) remove the flag | // just (try to) remove the flag | ||||
getNodeConfig().del(REDIS_LOG_FLAG_KEY); | getNodeConfig().del(REDIS_LOG_FLAG_KEY); | ||||
@@ -8,8 +8,11 @@ import bubble.model.bill.BubblePlan; | |||||
import bubble.model.cloud.BubbleNetwork; | import bubble.model.cloud.BubbleNetwork; | ||||
import bubble.model.cloud.BubbleNode; | import bubble.model.cloud.BubbleNode; | ||||
import bubble.service.boot.SelfNodeService; | import bubble.service.boot.SelfNodeService; | ||||
import lombok.NonNull; | |||||
import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
import java.util.Optional; | |||||
import static org.cobbzilla.util.daemon.ZillaRuntime.notSupported; | import static org.cobbzilla.util.daemon.ZillaRuntime.notSupported; | ||||
@Service | @Service | ||||
@@ -29,7 +32,12 @@ public class DbFilterSelfNodeService implements SelfNodeService { | |||||
@Override public BubblePlan getThisPlan() { return notSupported("getThisPlan"); } | @Override public BubblePlan getThisPlan() { return notSupported("getThisPlan"); } | ||||
@Override public Boolean getLogFlag() { return notSupported("getLogFlag"); } | |||||
@Override public void setLogFlag(boolean logFlag) { notSupported("setLogFlag"); } | |||||
@Override public boolean getLogFlag() { return notSupported("getLogFlag"); } | |||||
@Override @NonNull public Optional<Long> getLogFlagExpirationTime() { | |||||
return notSupported("getLogFlagExpirationTime"); | |||||
} | |||||
@Override public void setLogFlag(boolean logFlag, @NonNull final Optional<Integer> ttlInSeconds) { | |||||
notSupported("setLogFlag"); | |||||
} | |||||
} | } |
@@ -250,6 +250,16 @@ button_label_restore=Restore | |||||
button_description_restore=You will need full network restore key build from this bubble while if was running. | button_description_restore=You will need full network restore key build from this bubble while if was running. | ||||
restore_not_possible_nodes_exist_html=Cannot restore bubbles with existing nodes. Please contact <a href="mailto:support@getbubblenow.com">support@getbubblenow.com</a> | restore_not_possible_nodes_exist_html=Cannot restore bubbles with existing nodes. Please contact <a href="mailto:support@getbubblenow.com">support@getbubblenow.com</a> | ||||
# Network Page - Log flag | |||||
node_logs_enabled=logs enabled | |||||
node_logs_until=until | |||||
button_node_logs_disable=Disable Logs | |||||
node_logs_disable_after=Disable Logging After | |||||
node_logs_days=Days | |||||
button_node_logs_set_disable_after=Set | |||||
node_logs_disabled=logs are disabled | |||||
button_node_logs_enable=Enable Logs | |||||
# Network Page - Danger Zone | # Network Page - Danger Zone | ||||
title_network_danger_zone=Danger Zone | title_network_danger_zone=Danger Zone | ||||
link_network_action_stop=Stop | link_network_action_stop=Stop | ||||