diff --git a/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/executor/ComponentCommandExecutor.java b/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/executor/ComponentCommandExecutor.java index c7af474315b61ca4fe31f18ac754193b0366a8b0..ae38bb7d77d18b3f95e64cc6dd891afe8837bb04 100644 --- a/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/executor/ComponentCommandExecutor.java +++ b/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/executor/ComponentCommandExecutor.java @@ -18,6 +18,9 @@ */ package org.apache.bigtop.manager.agent.executor; +import lombok.extern.slf4j.Slf4j; +import org.apache.bigtop.manager.agent.holder.SpringContextHolder; +import org.apache.bigtop.manager.common.message.entity.command.CommandLogMessage; import org.apache.bigtop.manager.common.message.entity.command.CommandMessageType; import org.apache.bigtop.manager.common.message.entity.payload.CommandPayload; import org.apache.bigtop.manager.common.shell.ShellResult; @@ -27,8 +30,6 @@ import org.apache.bigtop.manager.stack.core.executor.StackExecutor; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Scope; -import lombok.extern.slf4j.Slf4j; - @Slf4j @org.springframework.stereotype.Component @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) @@ -49,9 +50,20 @@ public class ComponentCommandExecutor extends AbstractCommandExecutor { CommandPayload commandPayload = JsonUtils.readFromString(commandRequestMessage.getMessagePayload(), CommandPayload.class); log.info("[agent executeTask] taskEvent is: {}", commandRequestMessage); - ShellResult shellResult = StackExecutor.execute(commandPayload); + ShellResult shellResult = StackExecutor.execute(commandPayload, this::writeBackTaskLog); commandResponseMessage.setCode(shellResult.getExitCode()); commandResponseMessage.setResult(shellResult.getResult()); } + + private void writeBackTaskLog(String log) { + CommandLogMessage logMessage = new CommandLogMessage(); + logMessage.setLog(log); + logMessage.setMessageId(commandRequestMessage.getMessageId()); + logMessage.setHostname(commandRequestMessage.getHostname()); + logMessage.setTaskId(commandRequestMessage.getTaskId()); + logMessage.setStageId(commandRequestMessage.getStageId()); + logMessage.setJobId(commandRequestMessage.getJobId()); + SpringContextHolder.getAgentWebSocket().sendMessage(logMessage); + } } diff --git a/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/ws/AgentWebSocketHandler.java b/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/ws/AgentWebSocketHandler.java index afda640c51a4f14bfbae7b197587fb8948eff932..a73320b505309ec0bf21375e10c0e306066bb4bf 100644 --- a/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/ws/AgentWebSocketHandler.java +++ b/bigtop-manager-agent/src/main/java/org/apache/bigtop/manager/agent/ws/AgentWebSocketHandler.java @@ -18,8 +18,12 @@ */ package org.apache.bigtop.manager.agent.ws; -import static org.apache.bigtop.manager.common.constants.Constants.WS_BINARY_MESSAGE_SIZE_LIMIT; - +import com.sun.management.OperatingSystemMXBean; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Resource; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; import org.apache.bigtop.manager.agent.holder.SpringContextHolder; import org.apache.bigtop.manager.agent.scheduler.CommandScheduler; import org.apache.bigtop.manager.common.config.ApplicationConfig; @@ -31,18 +35,6 @@ import org.apache.bigtop.manager.common.message.entity.pojo.HostInfo; import org.apache.bigtop.manager.common.message.serializer.MessageDeserializer; import org.apache.bigtop.manager.common.utils.os.OSDetection; import org.apache.bigtop.manager.common.ws.AbstractBinaryWebSocketHandler; - -import java.lang.management.ManagementFactory; -import java.math.BigDecimal; -import java.net.InetAddress; -import java.text.MessageFormat; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import jakarta.annotation.Nonnull; -import jakarta.annotation.Resource; - import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; @@ -51,17 +43,19 @@ import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.client.standard.StandardWebSocketClient; -import com.sun.management.OperatingSystemMXBean; +import java.lang.management.ManagementFactory; +import java.math.BigDecimal; +import java.net.InetAddress; +import java.text.MessageFormat; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; +import static org.apache.bigtop.manager.common.constants.Constants.WS_BINARY_MESSAGE_SIZE_LIMIT; @Slf4j @Component -public class AgentWebSocketHandler extends AbstractBinaryWebSocketHandler - implements - ApplicationListener { +public class AgentWebSocketHandler extends AbstractBinaryWebSocketHandler implements ApplicationListener { @Resource private ApplicationConfig applicationConfig; diff --git a/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/message/entity/command/CommandLogMessage.java b/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/message/entity/command/CommandLogMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..be32f02bd03230fd7cbd8797055edec12be0000d --- /dev/null +++ b/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/message/entity/command/CommandLogMessage.java @@ -0,0 +1,40 @@ +/* + * 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 + * + * https://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.bigtop.manager.common.message.entity.command; + +import lombok.*; +import org.apache.bigtop.manager.common.message.entity.BaseMessage; + +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@NoArgsConstructor +@AllArgsConstructor +public class CommandLogMessage extends BaseMessage { + + private String log; + + private String hostname; + + private Long jobId; + + private Long stageId; + + private Long taskId; +} diff --git a/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/message/entity/command/CommandMessageType.java b/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/message/entity/command/CommandMessageType.java index dd51575060a8446b0db773800abcb235db712d59..54cbb72a8ae9424b1deddf642dca4f0c5f68b35b 100644 --- a/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/message/entity/command/CommandMessageType.java +++ b/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/message/entity/command/CommandMessageType.java @@ -25,4 +25,7 @@ public enum CommandMessageType { HOST_CHECK, CACHE_DISTRIBUTE, + + TASK_LOG, + ; } diff --git a/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/message/serializer/KryoPoolHolder.java b/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/message/serializer/KryoPoolHolder.java index ae0564a6046ad6567cc4945d0577504635973d56..6092f176760b30fa3a4e2effd31f7c966f0fc600 100644 --- a/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/message/serializer/KryoPoolHolder.java +++ b/bigtop-manager-common/src/main/java/org/apache/bigtop/manager/common/message/serializer/KryoPoolHolder.java @@ -18,22 +18,18 @@ */ package org.apache.bigtop.manager.common.message.serializer; +import com.esotericsoftware.kryo.Kryo; +import com.esotericsoftware.kryo.util.Pool; import org.apache.bigtop.manager.common.enums.Command; import org.apache.bigtop.manager.common.message.entity.BaseMessage; import org.apache.bigtop.manager.common.message.entity.BaseRequestMessage; import org.apache.bigtop.manager.common.message.entity.BaseResponseMessage; import org.apache.bigtop.manager.common.message.entity.HeartbeatMessage; +import org.apache.bigtop.manager.common.message.entity.command.CommandLogMessage; import org.apache.bigtop.manager.common.message.entity.command.CommandMessageType; import org.apache.bigtop.manager.common.message.entity.command.CommandRequestMessage; import org.apache.bigtop.manager.common.message.entity.command.CommandResponseMessage; -import org.apache.bigtop.manager.common.message.entity.pojo.ClusterInfo; -import org.apache.bigtop.manager.common.message.entity.pojo.ComponentInfo; -import org.apache.bigtop.manager.common.message.entity.pojo.CustomCommandInfo; -import org.apache.bigtop.manager.common.message.entity.pojo.HostCheckType; -import org.apache.bigtop.manager.common.message.entity.pojo.HostInfo; -import org.apache.bigtop.manager.common.message.entity.pojo.OSSpecificInfo; -import org.apache.bigtop.manager.common.message.entity.pojo.RepoInfo; -import org.apache.bigtop.manager.common.message.entity.pojo.ScriptInfo; +import org.apache.bigtop.manager.common.message.entity.pojo.*; import java.math.BigDecimal; import java.sql.Timestamp; @@ -42,12 +38,9 @@ import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; -import com.esotericsoftware.kryo.Kryo; -import com.esotericsoftware.kryo.util.Pool; - public class KryoPoolHolder { - private static final Pool KRYO_POOL = new Pool(true, false, 16) { + private static final Pool KRYO_POOL = new Pool<>(true, false, 16) { @Override protected Kryo create() { @@ -61,6 +54,7 @@ public class KryoPoolHolder { kryo.register(HeartbeatMessage.class); kryo.register(CommandResponseMessage.class); kryo.register(CommandRequestMessage.class); + kryo.register(CommandLogMessage.class); // message pojo kryo.register(HostInfo.class); diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/JobController.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/JobController.java index 39211131793e740c8f998b250a4223693e2fbe36..f1f59be74dca655afa20ac66ef91f54d7daf97f7 100644 --- a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/JobController.java +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/JobController.java @@ -18,25 +18,22 @@ */ package org.apache.bigtop.manager.server.controller; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; import org.apache.bigtop.manager.server.model.vo.JobVO; import org.apache.bigtop.manager.server.service.JobService; import org.apache.bigtop.manager.server.utils.ResponseEntity; - -import java.util.List; - -import jakarta.annotation.Resource; - import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.Parameters; -import io.swagger.v3.oas.annotations.enums.ParameterIn; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.List; @Tag(name = "Job Controller") @RestController diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/SseController.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/SseController.java new file mode 100644 index 0000000000000000000000000000000000000000..d62ac703a2ae15a389eeb268094ca2c73ff4c8b9 --- /dev/null +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/controller/SseController.java @@ -0,0 +1,75 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; + +import java.io.IOException; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +@Tag(name = "Sse Controller") +@RestController +@RequestMapping("/sse/clusters/{clusterId}") +public class SseController { + + private final ExecutorService executor = Executors.newCachedThreadPool(); + + @Operation(summary = "get task log", description = "Get a task log") + @GetMapping("/tasks/{id}/log") + public SseEmitter log(@PathVariable Long id, @PathVariable Long clusterId) { + SseEmitter emitter = new SseEmitter(); + + executor.execute(() -> { + try { + for (int i = 0; i < 3; i++) { + emitter.send("[INFO ] " + getFormattedTime() + " - " + "This info message!"); +// emitter.send("[WARN ] " + getFormattedTime() + " - " + "This warn message!"); +// emitter.send("[ERROR] " + getFormattedTime() + " - " + "This error message!"); + Thread.sleep(1000); + } + emitter.complete(); + } catch (IOException | InterruptedException e) { + emitter.completeWithError(e); + } + }); + + return emitter; + } + + private String getFormattedTime() { + ZoneId zoneId = ZoneOffset.systemDefault(); + ZonedDateTime zonedDateTime = ZonedDateTime.now(zoneId); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); + String time = zonedDateTime.format(formatter); + String offset = zonedDateTime.getOffset().getId().replace("Z", "+00:00"); + + return time + " " + offset; + } +} diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/ClusterServiceImpl.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/ClusterServiceImpl.java index c9147b25e02100a3fc6682d6bdeb31d2b9d4c90a..2047daa2662e418bbc6b4b27f0257c0f85201a02 100644 --- a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/ClusterServiceImpl.java +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/ClusterServiceImpl.java @@ -18,6 +18,8 @@ */ package org.apache.bigtop.manager.server.service.impl; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; import org.apache.bigtop.manager.common.enums.MaintainState; import org.apache.bigtop.manager.dao.entity.Cluster; import org.apache.bigtop.manager.dao.entity.Repo; @@ -39,10 +41,6 @@ import org.apache.bigtop.manager.server.utils.StackUtils; import java.util.ArrayList; import java.util.List; -import jakarta.annotation.Resource; - -import lombok.extern.slf4j.Slf4j; - @Slf4j @org.springframework.stereotype.Service public class ClusterServiceImpl implements ClusterService { diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/JobServiceImpl.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/JobServiceImpl.java index c79e97757ae5b7793e94fe6079a005ece3c45f2e..ba67210b1e51e6bd32360297ce8ab7df933b6513 100644 --- a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/JobServiceImpl.java +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/service/impl/JobServiceImpl.java @@ -18,18 +18,16 @@ */ package org.apache.bigtop.manager.server.service.impl; +import jakarta.annotation.Resource; import org.apache.bigtop.manager.dao.entity.Job; import org.apache.bigtop.manager.dao.repository.JobRepository; import org.apache.bigtop.manager.server.model.mapper.JobMapper; import org.apache.bigtop.manager.server.model.vo.JobVO; import org.apache.bigtop.manager.server.service.JobService; +import org.springframework.stereotype.Service; import java.util.List; -import jakarta.annotation.Resource; - -import org.springframework.stereotype.Service; - @Service public class JobServiceImpl implements JobService { @@ -38,15 +36,16 @@ public class JobServiceImpl implements JobService { @Override public List list(Long clusterId) { - // PageQuery pageQuery = PageUtils.getPageQuery(); - // Pageable pageable = PageRequest.of(pageQuery.getPageNum(), pageQuery.getPageSize(), pageQuery.getSort()); - // Page page; - // if (ClusterUtils.isNoneCluster(clusterId)) { - // page = jobRepository.findAllByClusterIsNull(pageable); - // } else { - // page = jobRepository.findAllByClusterId(clusterId, pageable); - // } - +// PageQuery pageQuery = PageUtils.getPageQuery(); +// Pageable pageable = PageRequest.of(pageQuery.getPageNum(), pageQuery.getPageSize(), pageQuery.getSort()); +// Page page; +// if (ClusterUtils.isNoneCluster(clusterId)) { +// page = jobRepository.findAllByClusterIsNull(pageable); +// } else { +// page = jobRepository.findAllByClusterId(clusterId, pageable); +// } +// +// return PageVO.of(page); List jobs = jobRepository.findAllByClusterId(clusterId); return JobMapper.INSTANCE.fromEntity2VO(jobs); diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/ws/ServerWebSocketHandler.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/ws/ServerWebSocketHandler.java index 90d548fa4e3d0cb7b95933aeb0685f7cbad68bc6..84d40a07d1c59e768e62f9243d28f25314573d1c 100644 --- a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/ws/ServerWebSocketHandler.java +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/ws/ServerWebSocketHandler.java @@ -21,6 +21,7 @@ package org.apache.bigtop.manager.server.ws; import org.apache.bigtop.manager.common.message.entity.BaseMessage; import org.apache.bigtop.manager.common.message.entity.BaseRequestMessage; import org.apache.bigtop.manager.common.message.entity.HeartbeatMessage; +import org.apache.bigtop.manager.common.message.entity.command.CommandLogMessage; import org.apache.bigtop.manager.common.message.entity.command.CommandResponseMessage; import org.apache.bigtop.manager.common.message.entity.pojo.HostInfo; import org.apache.bigtop.manager.common.ws.AbstractBinaryWebSocketHandler; @@ -88,6 +89,10 @@ public class ServerWebSocketHandler extends AbstractBinaryWebSocketHandler { handleHeartbeatMessage(session, heartbeatMessage); } else if (baseMessage instanceof CommandResponseMessage commandResponseMessage) { super.handleResponseMessage(commandResponseMessage); + } else if (baseMessage instanceof CommandLogMessage commandLogMessage) { + System.out.println("-------------------------- Task Log Begin --------------------------"); + System.out.println(commandLogMessage.getLog()); + System.out.println("-------------------------- Task Log End --------------------------"); } else { log.error("Unrecognized message type: {}", baseMessage.getClass().getSimpleName()); } diff --git a/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/executor/StackExecutor.java b/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/executor/StackExecutor.java index 6d12d4c203ba839e66d71006fdf58a86c0203be0..1e233aa709e3be885ebe3b915d7855d4224d8230 100644 --- a/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/executor/StackExecutor.java +++ b/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/executor/StackExecutor.java @@ -28,10 +28,12 @@ import org.apache.bigtop.manager.spi.stack.Hook; import org.apache.bigtop.manager.spi.stack.Params; import org.apache.bigtop.manager.spi.stack.Script; import org.apache.bigtop.manager.stack.common.exception.StackException; +import org.apache.bigtop.manager.stack.core.log.TaskLogWriter; import java.lang.reflect.Method; import java.util.List; import java.util.Map; +import java.util.function.Consumer; import lombok.extern.slf4j.Slf4j; @@ -81,7 +83,13 @@ public class StackExecutor { } public static ShellResult execute(CommandPayload commandPayload) { + return execute(commandPayload, s -> {}); + } + + public static ShellResult execute(CommandPayload commandPayload, Consumer consumer) { try { + TaskLogWriter.setWriter(consumer); + String command; Script script; if (commandPayload.getCommand().name().equals(Command.CUSTOM.name())) { @@ -103,6 +111,7 @@ public class StackExecutor { runBeforeHook(command); + TaskLogWriter.info("abcdefghijklmnopqrstuvwxyz"); log.info("execute [{}] : [{}] started.", script.getName(), method.getName()); ShellResult result = (ShellResult) method.invoke(script, params); log.info("execute [{}] : [{}] complete, result: [{}]", script.getName(), method.getName(), result); @@ -113,6 +122,8 @@ public class StackExecutor { } catch (Exception e) { log.info("Execute for commandPayload [{}] Error!!!", commandPayload, e); return ShellResult.fail(); + } finally { + TaskLogWriter.clearWriter(); } } } diff --git a/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/log/TaskLogWriter.java b/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/log/TaskLogWriter.java new file mode 100644 index 0000000000000000000000000000000000000000..d14020c3a28cc1f5e14e273be2f70deec3595ff9 --- /dev/null +++ b/bigtop-manager-stack/bigtop-manager-stack-core/src/main/java/org/apache/bigtop/manager/stack/core/log/TaskLogWriter.java @@ -0,0 +1,66 @@ +/* + * 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 + * + * https://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.bigtop.manager.stack.core.log; + +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.function.Consumer; + +public class TaskLogWriter { + + private static Consumer writer; + + public static void setWriter(Consumer writer) { + TaskLogWriter.writer = writer; + } + + public static void info(String str) { + if (TaskLogWriter.writer != null) { + TaskLogWriter.writer.accept("[INFO ] " + getFormattedTime() + " - " + str); + } + } + + public static void warn(String str) { + if (TaskLogWriter.writer != null) { + TaskLogWriter.writer.accept("[WARN ] " + getFormattedTime() + " - " + str); + } + } + + public static void error(String str) { + if (TaskLogWriter.writer != null) { + TaskLogWriter.writer.accept("[ERROR] " + getFormattedTime() + " - " + str); + } + } + + private static String getFormattedTime() { + ZoneId zoneId = ZoneOffset.systemDefault(); + ZonedDateTime zonedDateTime = ZonedDateTime.now(zoneId); + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); + String time = zonedDateTime.format(formatter); + String offset = zonedDateTime.getOffset().getId().replace("Z", "+00:00"); + + return time + " " + offset; + } + + public static void clearWriter() { + TaskLogWriter.writer = null; + } +}