-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Expand file tree
/
Copy pathjmx.go
More file actions
130 lines (111 loc) · 3.34 KB
/
jmx.go
File metadata and controls
130 lines (111 loc) · 3.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package frameworks
import (
"fmt"
"os"
"strconv"
"github.com/cloudfoundry/java-buildpack/src/java/common"
)
// JmxFramework implements JMX (Java Management Extensions) support
// Enables remote JMX monitoring and management
type JmxFramework struct {
context *common.Context
}
// NewJmxFramework creates a new JMX framework instance
func NewJmxFramework(ctx *common.Context) *JmxFramework {
return &JmxFramework{context: ctx}
}
// Detect checks if JMX should be enabled
func (j *JmxFramework) Detect() (string, error) {
// Check if JMX is enabled in configuration
config, err := j.loadConfig()
if err != nil {
j.context.Log.Warning("Failed to load jmx config: %s", err.Error())
return "", nil // Don't fail the build
}
if !config.isEnabled() {
return "", nil
}
return "JMX", nil
}
// Supply performs JMX setup during supply phase
func (j *JmxFramework) Supply() error {
config, err := j.loadConfig()
if err != nil {
j.context.Log.Warning("Failed to load debug config: %s", err.Error())
return nil // Don't fail the build
}
port := config.getPort()
j.context.Log.BeginStep("JMX enabled on port %d", port)
return nil
}
// Finalize adds JMX options to JAVA_OPTS via profile.d script
func (j *JmxFramework) Finalize() error {
config, err := j.loadConfig()
if err != nil {
j.context.Log.Warning("Failed to load debug config: %s", err.Error())
return nil // Don't fail the build
}
port := config.getPort()
// Build JMX system properties
jmxOpts := fmt.Sprintf(
"-Djava.rmi.server.hostname=127.0.0.1 "+
"-Dcom.sun.management.jmxremote.authenticate=false "+
"-Dcom.sun.management.jmxremote.ssl=false "+
"-Dcom.sun.management.jmxremote.port=%d "+
"-Dcom.sun.management.jmxremote.rmi.port=%d",
port, port,
)
// Write JAVA_OPTS to .opts file with priority 29 (Ruby buildpack line 63)
if err := writeJavaOptsFile(j.context, 29, "jmx", jmxOpts); err != nil {
return fmt.Errorf("failed to write java_opts file: %w", err)
}
return nil
}
func (j *JmxFramework) loadConfig() (*jmxConfig, error) {
// initialize default values
jConfig := jmxConfig{
Enabled: false,
Port: 5000,
}
config := os.Getenv("JBP_CONFIG_JMX")
if config != "" {
yamlHandler := common.YamlHandler{}
err := yamlHandler.ValidateFields([]byte(config), &jConfig)
if err != nil {
j.context.Log.Warning("Unknown user config values: %s", err.Error())
}
// overlay JBP_CONFIG_JMX over default values
if err = yamlHandler.Unmarshal([]byte(config), &jConfig); err != nil {
return nil, fmt.Errorf("failed to parse JBP_CONFIG_JMX: %w", err)
}
}
return &jConfig, nil
}
// isEnabled checks if JMX is enabled
func (j *jmxConfig) isEnabled() bool {
// Check BPL_JMX_ENABLED first (Cloud Native Buildpacks convention)
bplEnabled := os.Getenv("BPL_JMX_ENABLED")
if bplEnabled == "true" || bplEnabled == "1" {
return true
}
if bplEnabled == "false" || bplEnabled == "0" {
return false
}
// Check JBP_CONFIG_JMX environment variable (Java Buildpack convention)
return j.Enabled
}
// getPort returns the JMX port
func (j *jmxConfig) getPort() int {
// Check BPL_JMX_PORT first (Cloud Native Buildpacks convention)
bplPort := os.Getenv("BPL_JMX_PORT")
if bplPort != "" {
if port, err := strconv.Atoi(bplPort); err == nil && port > 0 {
return port
}
}
return j.Port
}
type jmxConfig struct {
Enabled bool `yaml:"enabled"`
Port int `yaml:"port"`
}